Our project is embracing the new functional React components and making heavy use of the various hooks, including useState
.
Unlike a React Class's setState()
method, the setter returned by useState() fully replaces the state instead of merging .
When the state is a map and I need to remove a key I clone the existing state, delete the key, then set the new state (as shown below)
[errors, setErrors] = useState({})
...
const onChange = (id, validate) => {
const result = validate(val);
if (!result.valid) {
setErrors({
...errors,
[fieldId]: result.message
})
}
else {
const newErrors = {...errors};
delete newErrors[id];
setErrors(newErrors);
}
Is there a better alternative (better being more efficient and/or standard)?
If you need more control when setting a state via hooks, look at the useReducer
hook .
This hook behaves like a reducer in redux - a function that receives the current state, and an action, and transforms the current state according to the action to create a new state.
Example (not tested):
const reducer = (state, { type, payload }) => {
switch(type) {
case 'addError':
return { ...state, ...payload };
case 'removeError':
const { [payload.id]: _, ...newState };
return newState;
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, {});
...
const onChange = (id, validate) => {
const result = validate(val);
if (!result.valid) {
dispatch({ type: 'addError', payload: { [id]: result.message }})
}
else {
dispatch({ type: 'removeError', payload: id })
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.