Reputation: 1124
Hook
export const useCreateAccount = () => {
const [state, setState] = useState(initialState)
const onChangeInput: ChangeEventFunction = useCallback(({ target }) => {
if (!target.files) {
return setState({ ...state, [target.name]: target.value })
}
setState({ ...state, [target.name]: target.files[0] })
}, [])
return { onChangeInput }
}
Component
const { onChangeInput } = useCreateAccount()
<form>
<input name="name1" onChange={onChangeInput}>
<input name="name2" onChange={onChangeInput}>
</form>
Every time I do some change in second input(name2) the previous state(name1) of the component has been lost(reset to initial state), The reason I use 'useCallback', I only need one instance of 'onChangeInput'
But if I remove 'useCallback', state is keeping the previous values(name1)
I can't understand this behavior in hooks, can someone elaborate more on this?
Upvotes: 2
Views: 1800
Reputation: 19194
From the docs:
Any function inside a component, including event handlers and effects, “sees” the props and state from the render it was created in.
Here, when you are using useCallback
, the function has been defined in it's initial render and has the initial state defined then. This is the reason why useCallback
has a depedency array that can be used to refresh the function and values used inside it.
But you cannot use state
as a dependency because you are setting the same inside it, instead you can use the functional version of setState
so as to get the previous values of state instead of reffering to the central one.
const onChangeInput: ChangeEventFunction = useCallback(({ target }) => {
if (!target.files) {
return setState(prevState => ({ ...prevState, [target.name]: target.value }));
}
setState(prevState => ({ ...prevState, [target.name]: target.files[0] }))
}, [])
Upvotes: 1