We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
复现组件:
function Components() { const [value, setValue] = useState([ { label: '1' } ]); useDeepCompareEffect(() => { console.log('触发'); }, [value]); const handleSearch = (valueStr: string) => { const newValue = [...value]; // newValue[0].label = valueStr; // 这么写不会触发 useDeepCompareEffect newValue[0] = { label: valueStr }; // 这么写可以 触发 useDeepCompareEffect setValue(newValue); }; const handleClick = () => { console.log('点击', value); }; return ( <div id='box'> {value.map((item, index) => { return ( <div key={index}> <Input value={item.label} onChange={(e) => { handleSearch(e.target.value); }} /> <Button onClick={handleClick}>获取</Button> </div> ); })} </div> ); }
本质上是因为ref缓存了之前的对象,如果是通过直接修改对象的值进行的变更,那么在比较的时候,也是拿的最新的已经产生变更的ref进行比较。这样子并不会触发useDeepCompareEffect 的回调,可以考虑改成clone快照 使其与外部环境解耦。
useDeepCompareEffect
hooks/packages/hooks/src/createDeepCompareEffect/index.ts
Line 15 in c7bb04c
The text was updated successfully, but these errors were encountered:
我觉得这个问题的本质是setState时,newValue[0].label = valueStr,仅对value进行了浅拷贝,label的引用地址是没变的。 useDeepCompareEffect 使用的react-fast-compare 是递归比较,先比较引用,再进行值对比。因此label的比较结果认为是相同的。
如虑改成clone,useDeepCompareEffect的性能会变得很差,甚至即使dependence没变时,也会出现大量无效对比。
Sorry, something went wrong.
建议使用immerjs
No branches or pull requests
复现组件:
本质上是因为ref缓存了之前的对象,如果是通过直接修改对象的值进行的变更,那么在比较的时候,也是拿的最新的已经产生变更的ref进行比较。这样子并不会触发
useDeepCompareEffect
的回调,可以考虑改成clone快照 使其与外部环境解耦。hooks/packages/hooks/src/createDeepCompareEffect/index.ts
Line 15 in c7bb04c
The text was updated successfully, but these errors were encountered: