Skip to content

Commit a0f67cb

Browse files
authored
Fixed destroyOnUnregister bug (#537)
* Fixed destroyOnUnregister bug * Made work with fields added after original render
1 parent 6b67ce1 commit a0f67cb

File tree

5 files changed

+113
-26
lines changed

5 files changed

+113
-26
lines changed

package-lock.json

Lines changed: 33 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"eslint-plugin-react": "^7.13.0",
6363
"eslint-plugin-react-hooks": "^1.6.0",
6464
"fast-deep-equal": "^2.0.1",
65-
"final-form": "^4.15.0",
65+
"final-form": "^4.16.0",
6666
"flow-bin": "^0.98.1",
6767
"glow": "^1.2.2",
6868
"husky": "^2.4.1",
@@ -89,7 +89,7 @@
8989
"typescript": "^3.5.2"
9090
},
9191
"peerDependencies": {
92-
"final-form": "^4.15.0",
92+
"final-form": "^4.16.0",
9393
"react": "^16.8.0"
9494
},
9595
"lint-staged": {

src/ReactFinalForm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function ReactFinalForm<FormValues: FormValuesShape>({
134134
form.setConfig('debug', debug)
135135
})
136136
useWhenValueChanges(destroyOnUnregister, () => {
137-
form.setConfig('destroyOnUnregister', destroyOnUnregister)
137+
form.destroyOnUnregister = !!destroyOnUnregister
138138
})
139139
useWhenValueChanges(
140140
initialValues,

src/ReactFinalForm.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,4 +940,65 @@ describe('ReactFinalForm', () => {
940940
expect(formMock.mock.calls[1][0]).toBe('name')
941941
expect(formMock.mock.calls[1][2].active).toBe(true) // default subscription
942942
})
943+
944+
it('should not destroy on unregister on initial unregister', () => {
945+
// https://github.com/final-form/react-final-form/issues/523
946+
const { getByTestId } = render(
947+
<Form
948+
onSubmit={onSubmitMock}
949+
initialValues={{ name: 'erikras' }}
950+
destroyOnUnregister
951+
>
952+
{({ handleSubmit }) => (
953+
<form onSubmit={handleSubmit}>
954+
<Field name="name" component="input" data-testid="name" />
955+
</form>
956+
)}
957+
</Form>
958+
)
959+
960+
expect(getByTestId('name')).toBeDefined()
961+
expect(getByTestId('name').value).toBe('erikras')
962+
fireEvent.focus(getByTestId('name'))
963+
expect(getByTestId('name').value).toBe('erikras')
964+
})
965+
966+
it('should not destroy on unregister on initial register/unregister of new field', () => {
967+
// https://github.com/final-form/react-final-form/issues/523
968+
const { getByTestId, queryByTestId, getByText } = render(
969+
<Form
970+
onSubmit={onSubmitMock}
971+
initialValues={{ name: 'erikras', password: 'f1nal-f0rm-RULEZ' }}
972+
destroyOnUnregister
973+
>
974+
{({ handleSubmit }) => (
975+
<form onSubmit={handleSubmit}>
976+
<Field name="name" component="input" data-testid="name" />
977+
<Toggle>
978+
{showPassword =>
979+
showPassword && (
980+
<Field
981+
name="password"
982+
component="input"
983+
type="password"
984+
data-testid="password"
985+
/>
986+
)
987+
}
988+
</Toggle>
989+
</form>
990+
)}
991+
</Form>
992+
)
993+
994+
expect(getByTestId('name')).toBeDefined()
995+
expect(getByTestId('name').value).toBe('erikras')
996+
fireEvent.focus(getByTestId('name'))
997+
expect(getByTestId('name').value).toBe('erikras')
998+
expect(queryByTestId('password')).toBe(null)
999+
fireEvent.click(getByText('Toggle'))
1000+
expect(getByTestId('password').value).toBe('f1nal-f0rm-RULEZ')
1001+
fireEvent.focus(getByTestId('password'))
1002+
expect(getByTestId('password').value).toBe('f1nal-f0rm-RULEZ')
1003+
})
9431004
})

src/useField.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,22 @@ function useField<FormValues: FormValuesShape>(
7272
const firstRender = React.useRef(true)
7373

7474
// synchronously register and unregister to query field state for our subscription on first render
75-
const [state, setState] = React.useState<FieldState>(
76-
(): FieldState => {
77-
let initialState: FieldState = {}
78-
register(state => {
79-
initialState = state
80-
})()
81-
return initialState
82-
}
83-
)
75+
const [state, setState] = React.useState<FieldState>((): FieldState => {
76+
let initialState: FieldState = {}
77+
78+
// temporarily disable destroyOnUnregister
79+
const destroyOnUnregister = form.destroyOnUnregister
80+
form.destroyOnUnregister = false
81+
82+
register(state => {
83+
initialState = state
84+
})()
85+
86+
// return destroyOnUnregister to its original value
87+
form.destroyOnUnregister = destroyOnUnregister
88+
89+
return initialState
90+
})
8491

8592
React.useEffect(
8693
() =>

0 commit comments

Comments
 (0)