react
中,通常使用 useState
定义一个状态数据,如:
const [count, setCount] = useState(0)
可以使用 setCount
函数更新状态
setCount(1)
// 或
setCount((prevCount) => prevCount + 1)
如果想在组件引入的外部函数中使用 count
或者更新 count
,就需要把 count
和 setCount
传入到这个外部函数中
import { increase } from './increaseCount'
export default function MyComponent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => increase(count, setCount)}></button>
<div>{ count }</div>
</div>
)
}
export function increase(count, setCount) {
// 使用
// todo...
// 更新
setCount((prevCount) => prevCount + 1)
// 或者
// setCount(count)
}
这样看来,更新 count
有点繁琐,有没有可能可以直接修改呢,就像普通对象那样
那必须有
通过自定义 hook
结合 Proxy
来实现
// useReactive.js
import { useMemo, useState } from 'react';
/**
* 响应式数据
* 和普通对象一样,直接修改
* @param props
*/
export default function useReactive<T extends object>(props: T) {
// useState的作用是触发react的自动更新
const [state, setState] = useState<T>(props);
return useMemo(() => {
const proxyState = new Proxy(state, {
set(target: T, p: string | symbol, value: any, receiver: any) {
// 更新state,触发页面自动更新
setState((prevState) => ({ ...prevState, [p]: value }));
return Reflect.set(target, p, value, receiver);
},
});
return proxyState;
}, []);
}
然后就可以在组件中愉快的使用啦
function MyComponent() {
const state = useReactive({
count: 0,
});
return (
<div>
<button onClick={() => state.count++}>+1</button>
<div>{state.count}</div>
</div>
);
}
// 或者,在外部函数中更新
function increaseCount(state: { count: number }) {
state.count++
}