React hooks are really easy to use, and the code is simpler than class components, but sometimes it is inconvenient to update the data of useState, such as when declaring an array or an object, you have to set it up Pass a function back and use the spread operator to combine objects
setValue((oldValue) => ({
...oldValue,
...newValue,
}));
I feel that it is not very beautiful to look at in the component, and if the component code is a little more, it takes three lines to update the data, especially when it is used in if/for or callback. A simple encapsulation makes it more elegant when updating data in components.
First write several utility functions isArray, isObject, isNotObject
function isArray(value) {
return value instanceof Array;
}
function isObject(value) {
return value instanceof Object && !(value instanceof Array);
}
function isNotObject(value) {
return typeof value !== "object";
}
Then in our custom hook function useSetState, declare the variable with the original useState, the variable can be returned directly, just do some operations on _setValue to return a new setValue.
In setValue, if initValue is an array, the new setValue is pushed when a single value is passed in, and merged when passing in an array; if initValue is an object, the incoming objects are merged, and an error is thrown when other types are passed in.
import { useState } from "react";
export default function useSetState(initValue) {
const [_value, _setValue] = useState(initValue);
function setValue(newValue) {
// 初始数据为 数组
if (isArray(initValue)) {
if (isArray(newValue)) {
_setValue((oldValue) => [...oldValue, ...newValue]);
} else {
_setValue((oldValue) => [...oldValue, newValue]);
}
}
// 初始数据为 对象
else if (isObject(initValue)) {
if (isObject(newValue)) {
_setValue((oldValue) => ({
...oldValue,
...newValue,
}));
} else {
throw new Error(`${JSON.stringify(newValue)} 与初始数据类型不符!`);
}
} else if (isNotObject(initValue)) {
_setValue(newValue);
}
}
return [_value, setValue];
}
Actual use effect
const [obj, setObj] = useSetState({
a: 1,
b: 2,
});
const [arr, setArr] = useSetState([{ id: 1 }, { id: 2 }]);
setObj({ c: 3 }); // {a: 1, b: 2, c: 3}
setArr({ id: 3 }); // [{ id: 1 }, { id: 2 },{ id: 3 }]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。