Skip to content
This repository was archived by the owner on Jan 14, 2021. It is now read-only.

Commit eabe7a8

Browse files
authored
Merge pull request #15 from RiccardoCampitelli/master-setValue-register-optional-#13
fix #13 setValue, register and unregister should be optional
2 parents e3f860a + 6c1f6db commit eabe7a8

File tree

3 files changed

+174
-5
lines changed

3 files changed

+174
-5
lines changed

src/index.test.tsx

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import * as React from 'react';
22
import { render, fireEvent } from '@testing-library/react';
33
import { RHFInput } from './index';
4+
import { FormContext } from 'react-hook-form';
5+
import { FormStateProxy } from 'react-hook-form/dist/types';
46

57
describe('React Hook Form Input', () => {
68
it('should render correctly', () => {
79
const setValue = () => {};
810
const register = () => () => {};
11+
const unregister = () => {};
912
const { asFragment } = render(
1013
<RHFInput
1114
setValue={setValue}
1215
register={register}
16+
unregister={unregister}
1317
name="test"
1418
as={<input />}
1519
/>,
@@ -21,10 +25,12 @@ describe('React Hook Form Input', () => {
2125
it('should register input when component mount', () => {
2226
const setValue = () => {};
2327
const register = jest.fn();
28+
const unregister = () => {};
2429
render(
2530
<RHFInput
2631
setValue={setValue}
2732
register={register}
33+
unregister={unregister}
2834
name="test"
2935
rules={{ required: true }}
3036
as={<input />}
@@ -82,10 +88,12 @@ describe('React Hook Form Input', () => {
8288
it('should update internal value when onChange fired', () => {
8389
const setValue = jest.fn();
8490
const register = () => () => {};
91+
const unregister = () => {};
8592
const { getByPlaceholderText } = render(
8693
<RHFInput
8794
setValue={setValue}
8895
register={register}
96+
unregister={unregister}
8997
name="test"
9098
as={<input placeholder="test" />}
9199
/>,
@@ -100,4 +108,144 @@ describe('React Hook Form Input', () => {
100108

101109
expect(setValue).toBeCalledWith('test', 'test', false);
102110
});
111+
112+
it('should use formContext when setValue prop not provided', () => {
113+
const record: Record<string, any> = {};
114+
const formState: FormStateProxy = {
115+
dirty: true,
116+
isSubmitted: true,
117+
isSubmitting: false,
118+
isValid: true,
119+
submitCount: 1,
120+
touched: [],
121+
};
122+
const methods = {
123+
setValue: jest.fn(),
124+
register: () => () => {},
125+
unregister: () => {},
126+
watch: () => () => {},
127+
reset: () => {},
128+
clearError: () => {},
129+
setError: () => {},
130+
triggerValidation: () => new Promise<boolean>(resolve => resolve(true)),
131+
getValues: () => record,
132+
handleSubmit: () => () => new Promise<void>(resolve => resolve()),
133+
errors: {},
134+
formState: formState,
135+
};
136+
137+
const register = () => () => {};
138+
const unregister = () => {};
139+
140+
const { getByPlaceholderText } = render(
141+
<FormContext {...methods}>
142+
<RHFInput
143+
name="test"
144+
as={<input placeholder="test" />}
145+
register={register}
146+
unregister={unregister}
147+
/>
148+
</FormContext>,
149+
);
150+
151+
const input = getByPlaceholderText('test');
152+
fireEvent.change(input, {
153+
target: {
154+
value: 'test',
155+
},
156+
});
157+
158+
expect(methods.setValue).toBeCalledWith('test', 'test', false);
159+
});
160+
161+
it('should use formContext when register prop not provided', () => {
162+
const record: Record<string, any> = {};
163+
const formState: FormStateProxy = {
164+
dirty: true,
165+
isSubmitted: true,
166+
isSubmitting: false,
167+
isValid: true,
168+
submitCount: 1,
169+
touched: [],
170+
};
171+
const methods = {
172+
setValue: () => {},
173+
register: jest.fn(),
174+
unregister: () => {},
175+
watch: () => () => {},
176+
reset: () => {},
177+
clearError: () => {},
178+
setError: () => {},
179+
triggerValidation: () => new Promise<boolean>(resolve => resolve(true)),
180+
getValues: () => record,
181+
handleSubmit: () => () => new Promise<void>(resolve => resolve()),
182+
errors: {},
183+
formState: formState,
184+
};
185+
186+
const setValue = () => {};
187+
const unregister = () => {};
188+
189+
render(
190+
<FormContext {...methods}>
191+
<RHFInput
192+
name="test"
193+
as={<input placeholder="test" />}
194+
setValue={setValue}
195+
rules={{ required: true }}
196+
unregister={unregister}
197+
/>
198+
</FormContext>,
199+
);
200+
201+
expect(methods.register).toBeCalledWith(
202+
{ name: 'test' },
203+
{ required: true },
204+
);
205+
});
206+
207+
it('should use formContext when unregister prop not provided', () => {
208+
const record: Record<string, any> = {};
209+
const formState: FormStateProxy = {
210+
dirty: true,
211+
isSubmitted: true,
212+
isSubmitting: false,
213+
isValid: true,
214+
submitCount: 1,
215+
touched: [],
216+
};
217+
const methods = {
218+
setValue: () => {},
219+
register: () => () => {},
220+
unregister: jest.fn(),
221+
watch: () => () => {},
222+
reset: () => {},
223+
clearError: () => {},
224+
setError: () => {},
225+
triggerValidation: () => new Promise<boolean>(resolve => resolve(true)),
226+
getValues: () => record,
227+
handleSubmit: () => () => new Promise<void>(resolve => resolve()),
228+
errors: {},
229+
formState: formState,
230+
};
231+
232+
const setValue = () => {};
233+
const register = () => () => {};
234+
235+
const { unmount } = render(
236+
<FormContext {...methods}>
237+
<RHFInput
238+
name="test"
239+
as={<input placeholder="test" />}
240+
setValue={setValue}
241+
rules={{ required: true }}
242+
register={register}
243+
/>
244+
</FormContext>,
245+
);
246+
247+
unmount();
248+
249+
expect(methods.unregister).toBeCalledWith('test');
250+
});
103251
});

src/index.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,30 @@ const RHFInput = React.memo(
4040
const [inputValue, setInputValue] = React.useState(defaultData);
4141
const valueRef = React.useRef(defaultData);
4242
const methods = useFormContext();
43-
const setValue = methods ? methods.setValue : setValueFromProp;
44-
const register = methods ? methods.register : registerFromProp;
45-
const unregister = methods ? methods.unregister : unregisterFromProp;
43+
const setValue =
44+
setValueFromProp !== undefined
45+
? setValueFromProp
46+
: methods
47+
? methods.setValue
48+
: () => {
49+
throw Error('Must provide setValue prop or formContext');
50+
};
51+
const register =
52+
registerFromProp !== undefined
53+
? registerFromProp
54+
: methods
55+
? methods.register
56+
: () => {
57+
throw Error('Must provide register prop or formContext');
58+
};
59+
const unregister =
60+
unregisterFromProp !== undefined
61+
? unregisterFromProp
62+
: methods
63+
? methods.unregister
64+
: () => {
65+
throw Error('Must provide unregister prop or formContext');
66+
};
4667

4768
const commonTask = (target: any) => {
4869
const data = getValue(target, { isCheckbox });

src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export type EventFunction = (
2929
};
3030

3131
export type Props = {
32-
setValue: (name: string, value: any, trigger?: boolean) => void;
33-
register: (ref: any, rules: ValidationOptions) => (name: string) => void;
32+
setValue?: (name: string, value: any, trigger?: boolean) => void;
33+
register?: (ref: any, rules: ValidationOptions) => (name: string) => void;
3434
unregister?: (name: string) => void;
3535
name: string;
3636
as: React.ReactElement<any>;

0 commit comments

Comments
 (0)