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;
代碼沙盒-在線運行
我學習了鉤子,人們告訴我不要更改嵌套物件。
我們應該保持原始狀態不變或使用https://github.com/immerjs/immer
但是上面的代碼也可以更新UI,為什么呢?
有什么form.avatar.deep.id =1;setForm({ ...form });缺點?
直接改變嵌套物件的屬性有什么壞處?
uj5u.com熱心網友回復:
什么是 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>
)
})
在上面的代碼中,memo和useEffect都被破壞了。memo如果 props 發生更改,則應該渲染組件,如果沒有更改則跳過渲染。但它看起來avatar永遠不會改變,因此它永遠不會重新渲染 . 同樣,如果組件確實渲染了,使用效果會永遠認為avatar沒有改變,不會重新運行效果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/527409.html
上一篇:在發送給客戶端之前修改回應
