-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathApiFormState.tsx
More file actions
87 lines (81 loc) · 2.93 KB
/
ApiFormState.tsx
File metadata and controls
87 lines (81 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import * as React from "react"
import * as typographyStyles from "../styles/typography.module.css"
import FormStateTable from "./FormStateTable"
import TabGroup from "./TabGroup"
import CodeArea from "./CodeArea"
import formStateUseEffect from "./codeExamples/formStateUseEffect"
import formStateUseEffectTs from "./codeExamples/formStateUseEffectTs"
export default React.memo(
({ api, currentLanguage }: { currentLanguage: string; api: any }) => {
return (
<>
<code className={typographyStyles.codeHeading}>
<h2>
formState: <span className={typographyStyles.typeText}>Object</span>
</h2>
</code>
{api.formState.description}
<FormStateTable currentLanguage={currentLanguage} api={api} />
<h2 id="rules" className={typographyStyles.rulesTitle}>
Rules
</h2>
<ul>
<li>
<p>
<code>formState</code> is wrapped with a{" "}
<a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"
target="_blank"
rel="noopener noreferrer"
>
defineProperty's <code>get</code> descriptor
</a>{" "}
to improve render performance and skip extra logic if specific
state is not subscribed to. Therefore make sure you invoke or read
it before a <code>render</code> in order to enable the state
update.
</p>
</li>
<li>
<p>
<code>formState</code> is updated in batch. If you want to
subscribe to <code>formState</code> via <code>useEffect</code>,
make sure that you place the entire <code>formState</code> in the
optional array.
</p>
<TabGroup buttonLabels={["snippet", "example"]}>
<CodeArea
rawData={`useEffect(() => {
if (formState.errors.firstName) {
// do the your logic here
}
}, [formState]); // ✅
// ❌ formState.errors will not trigger the useEffect
`}
/>
<CodeArea
rawData={formStateUseEffect}
tsRawData={formStateUseEffectTs}
/>
</TabGroup>
</li>
<li>
<p>
Pay attention to the logical operator when subscription to{" "}
<code>formState</code>.
</p>
<CodeArea
rawData={`// ❌ formState.isValid is accessed conditionally,
// so the formState with get descriptor does not subscribe to changes of that state
return <button disabled={!formState.isDirty || !formState.isValid} />;
// ✅ read all formState values to subscribe to changes
const { isDirty, isValid } = formState;
return <button disabled={!isDirty || !isValid} />;
`}
/>
</li>
</ul>
</>
)
}
)