From 15f0bcefe61f15d63e3161b27a2475e47c0c005d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C3=ADbal=20Svarcas?= Date: Mon, 15 May 2023 10:39:33 -0300 Subject: [PATCH 1/2] Fix custom onChange handlers should have access to updated context in puts value --- packages/ra-core/src/form/useInput.spec.tsx | 60 +++++++++++++++++++++ packages/ra-core/src/form/useInput.ts | 8 +-- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/packages/ra-core/src/form/useInput.spec.tsx b/packages/ra-core/src/form/useInput.spec.tsx index a989b5bb5e9..6b8e07ab5b5 100644 --- a/packages/ra-core/src/form/useInput.spec.tsx +++ b/packages/ra-core/src/form/useInput.spec.tsx @@ -17,6 +17,26 @@ const Input: FunctionComponent< return children(inputProps); }; +const InputWithCustomOnChange: FunctionComponent< + { + children: (props: ReturnType) => ReactElement; + } & InputProps & { getContextValue?: (value: string) => void } +> = ({ children, getContextValue, ...props }) => { + const { getValues } = useFormContext(); + + return ( + { + props.onChange(e); + getContextValue(getValues()[props.source]); + }} + > + {children} + + ); +}; + describe('useInput', () => { it('returns the props needed for an input', () => { let inputProps; @@ -106,6 +126,46 @@ describe('useInput', () => { expect(handleBlur).toHaveBeenCalled(); }); + it('custom onChange handler should have access to updated context input value', () => { + let targetValue, contextValue; + const handleChange = e => { + targetValue = e.target.value; + }; + const getContextValue = value => { + contextValue = value; + }; + + render( + +
+ + {({ id, field }) => ( + + )} + +
+
+ ); + const input = screen.getByLabelText('Title'); + + fireEvent.change(input, { + target: { value: 'Changed title' }, + }); + expect(targetValue).toBe('Changed title'); + expect(contextValue).toBe('Changed title'); + }); + describe('defaultValue', () => { it('applies the defaultValue when input does not have a value', () => { const onSubmit = jest.fn(); diff --git a/packages/ra-core/src/form/useInput.ts b/packages/ra-core/src/form/useInput.ts index 7a99e17dc60..adb494b4706 100644 --- a/packages/ra-core/src/form/useInput.ts +++ b/packages/ra-core/src/form/useInput.ts @@ -87,21 +87,21 @@ export const useInput = ( useApplyInputDefaultValues(props); const onBlur = useEvent((...event: any[]) => { + controllerField.onBlur(); if (initialOnBlur) { initialOnBlur(...event); } - controllerField.onBlur(); }); const onChange = useEvent((...event: any[]) => { - if (initialOnChange) { - initialOnChange(...event); - } const eventOrValue = (props.type === 'checkbox' && event[0]?.target?.value === 'on' ? event[0].target.checked : event[0]?.target?.value ?? event[0]) as any; controllerField.onChange(parse ? parse(eventOrValue) : eventOrValue); + if (initialOnChange) { + initialOnChange(...event); + } }); const field = { From caf4d468fc28229288fb9265866f550ae24b920e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C3=ADbal=20Svarcas?= Date: Mon, 15 May 2023 10:42:10 -0300 Subject: [PATCH 2/2] Change getContextValue for setContextValue --- packages/ra-core/src/form/useInput.spec.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ra-core/src/form/useInput.spec.tsx b/packages/ra-core/src/form/useInput.spec.tsx index 6b8e07ab5b5..603416bdb6e 100644 --- a/packages/ra-core/src/form/useInput.spec.tsx +++ b/packages/ra-core/src/form/useInput.spec.tsx @@ -20,8 +20,8 @@ const Input: FunctionComponent< const InputWithCustomOnChange: FunctionComponent< { children: (props: ReturnType) => ReactElement; - } & InputProps & { getContextValue?: (value: string) => void } -> = ({ children, getContextValue, ...props }) => { + } & InputProps & { setContextValue?: (value: string) => void } +> = ({ children, setContextValue, ...props }) => { const { getValues } = useFormContext(); return ( @@ -29,7 +29,7 @@ const InputWithCustomOnChange: FunctionComponent< {...props} onChange={e => { props.onChange(e); - getContextValue(getValues()[props.source]); + setContextValue(getValues()[props.source]); }} > {children} @@ -131,7 +131,7 @@ describe('useInput', () => { const handleChange = e => { targetValue = e.target.value; }; - const getContextValue = value => { + const setContextValue = value => { contextValue = value; }; @@ -142,7 +142,7 @@ describe('useInput', () => { source="title" resource="posts" onChange={handleChange} - getContextValue={getContextValue} + setContextValue={setContextValue} defaultValue="" > {({ id, field }) => (