I don't want to use single state variables or updating the whole state with functional components. I wrote a hook based on useReducer like below but I am not sure about the possible dangerous effects. Is it safe? Thanks.
import React, { useReducer } from "react";
export function useCustomState<T>(initialState: T) {
const reducer: React.Reducer<T, Partial<T>> = (prevState, newState) => ({
...prevState,
...newState,
});
return useReducer(reducer, initialState, (state) => state);
}
CodePudding user response:
It's not dangerous, but I think it's also not the best way to accomplish your goals. It seems like you're not understanding the differences between useState
and useReducer
and when you should use one or the other.
A "reducer" is a function that takes the previous state and an "action" and returns a new state. The action meant to be an instruction rather a state -- it's the job of the reducer to determine the next state based on that instruction. An action typically looks like {type: 'LOGGED_OUT'}
or {type: 'LOGGED_IN', payload: { userId: 12345, username: 'Some One' }
.
In your case, your "action" is the new state which you want to shallow merge with the existing state. In my opinion, you would be better off using useState
to achieve this.
export function useCustomState<T>(initialState: T) {
const [state, setState] = useState(initialState);
const update = (newState: Partial<T>) =>
setState(prevState => ({
...prevState,
...newState,
}));
return [state, update]
}
This hook returns a tuple that is similar to your typical [state, setState]
tuple, except that the update
function can accept a partial state that it will merge with the existing state.
CodePudding user response:
Yes, there is nothing wrong with writing a custom hook that wraps one or more existing hooks and adds logic or code that you do not want to duplicate.
You can see an example doing something similar on the React documentation about custom hooks.