lis*_*nge 3 javascript typescript reactjs react-hooks
import { useState } from "react";
function App() {
const [form, setForm] = useState({
usename: ``,
password: ``,
avatar: { id: 0, url: ``, deep: { id: 0 } },
});
return (
<div>
<h1>ID:{form.avatar.deep.id}</h1>
<h2
onClick={() => {
form.avatar.deep.id += 1;
setForm({ ...form });
}}
>
Change-ID
</h2>
</div>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
我学习了 reat hooks,人们告诉我不要更改嵌套对象。
我们应该保持原来的状态不变或者使用https://github.com/immerjs/immer
但是上面的代码也可以更新UI,为什么呢?
有什么form.avatar.deep.id+=1;setForm({ ...form });缺点?
直接改变嵌套对象的属性有什么缺点?
什么是 form.avatar.deep.id+=1;setForm({ ...form }); 缺点?
React 的设计考虑到了不可变状态。这允许进行非常便宜的===比较来判断事情是否发生了变化。您已经复制了form,这足以让此示例代码正常工作。新旧表单是不同的对象,因此当您设置状态时组件会重新呈现。
如果某段代码关心表单的一部分而不是整个表单,就会出现问题。如果一个组件想要检查是否form.avatar改变了,它会看到没有,它没有改变,但事实上它已经改变了!
例如,假设我们将一个Avatar组件拆分如下:
import { memo } from 'react';
function App() {
const [form, setForm] = useState({
usename: ``,
password: ``,
avatar: { id: 0, url: ``, deep: { id: 0 } },
});
return (
<div>
<Avatar avatar={form.avatar} />
<h2
onClick={() => {
form.avatar.deep.id += 1;
setForm({ ...form });
}}
>
Change-ID
</h2>
</div>
);
}
const Avatar = memo(function ({ avatar }) {
useEffect(() => {
// Supposed to do some stuff, if avatar has changed
}, [avatar]);
return (
<h1>ID:{avatar.deep.id}</h1>
)
})
Run Code Online (Sandbox Code Playgroud)
在上面的代码中, 和memo都useEffect被破坏了。memo如果 props 改变了,应该渲染组件,如果没有改变则跳过渲染。但它看起来avatar永远不会改变,因此它永远不会重新渲染。同样,如果组件确实渲染,则使用效果将永远认为avatar没有改变,并且不会重新运行效果。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |