import { useCallback, useState } from 'react';
const getType = (value) => {
const type = Object.prototype.toString.call(value);
if (type === '[object Object]') {
return 'isObject'
} else if (type === '[object Array]') {
return 'isArray'
}
return typeof value;
}
const useMerge = (initialState) => {
const [state, setState] = useState(initialState);
const stateType = getType(initialState);
const handleMerge = useCallback((handleObject = {}) => {
const { id, type, value } = handleObject;
const merge = (state) => {
let mergeData = {};
if (stateType === 'isObject') {
mergeData = {
...state,
...value
}
}
if (stateType === 'isArray') {
if (type === 'remove') {
mergeData = state.filter((item) => {
return item.id !== id
})
}
if (type === 'add') {
mergeData = [...state, value];
}
if (type === 'update') {
mergeData = state.map((item) => {
if (item.id === id) {
return {
...item,
...value
}
}
return item;
})
}
}
return mergeData;
}
setState((prevState) => merge(prevState))
}, [])
return [state, handleMerge];
}
export default useMerge;
1
cutemurphy2888 OP const [list, setList] = useMerge([{ id: 1, text: 'aa' }, { id: 2, text: 'bb' }]);
const changeTT = () => { setList({ type: 'update', id: 2, value: { text: 'dxx' } }) } |
2
nulIptr 2022-11-20 22:07:27 +08:00
没注释不知道干啥用的,没 type 懒得看
merge 函数可以拿到外面 |
3
cnhongwei 2022-11-20 22:55:35 +08:00
直接用 展开运算符或 filter + 展开运行 不就行了。
|
4
kid740246048 2022-11-20 23:01:28 +08:00
state 类的自定义 hook ,返回的 set 方法最好支持传入函数,参考 react 的这个类型
type SetStateAction<S> = S | ((prevState: S) => S); 一些场景下使用时可以避免把 state 本身加到依赖数组 |
5
nbhaohao 2022-11-21 09:00:20 +08:00
个人感觉这种需求没有不要单独一个 hook, handleMerge 是一个 util 方法, 其他地方如果需要这种 merge 的操作, 自行调用 merge 即可.
``` const [list, setList] = useState([{ id: 1, text: 'aa' }, { id: 2, text: 'bb' }]); const changeTT = () => { setList(merge(, list{ type: 'update', id: 2, value: { text: 'dxx' } })) } ``` |
7
ospider 2022-11-21 09:27:17 +08:00
为啥不用 ts
|
8
cutemurphy2888 OP @ospider 只有 50%的人在用·
|
9
lisongeee 2022-11-21 10:03:07 +08:00
看例子感觉不如<https://github.com/immerjs/immer> 好用
|
10
cutemurphy2888 OP @lisongeee 我看看·
|
11
xingguang 2022-11-21 15:57:07 +08:00
lodash 也有 merge 相关的库吧,没有必要重复造轮子,如果想要 render 的话就封装一个,用 useState 触发下 render
|
12
hb751968840 2022-11-21 17:31:52 +08:00
ts 还是有必要的,参考一下三年前写的 https://github.com/H-jx/use-model , 支持 immer.js 、immutable ,ts 自动推导
|