ES6 类应该直接用作 React 状态吗?
我想定义一个 ES6 类,它:
- 具有将在前端显示的成员变量。(对它们的更改会触发重新渲染)
- 具有在更改时定期将这些成员变量与我的后端同步的方法。
但是,至少据我所知,调用setState
似乎并没有差异类成员。
使用以下类:
class Document{
constructor(){
this.title = "";
this.body = "";
}
syncWithDatabase = async () => {
// do some logic to update the database
}
}
而这个组件:
// import Document from "...";
export default function Sandbox() {
const [document, setDocument] = useState(new Document());
const [renderTrigger, setRenderTrigger] = useState(false);
return (
<div>
<div>{document.title}</div>
<div>{document.body}</div>
<button
onClick={() => {
document.title = 'Some Default Title';
document.body = 'lorem text';
document.syncWithDatabase(); // being able to take this type of action in this way is why I'm trying to use classes.
setDocument(document);
}}
>
Set Canned Data
</button>
<div>Render trigger is: {renderTrigger ? 'true' : 'false'}</div>
<button onClick={() => setRenderTrigger(true)}>Force Render</button>
</div>
);
}
单击第一个按钮将在持有的 react 状态的实例上设置标题和正文Document
但它不会更新 UI。
单击第二个按钮以我相信会起作用的方式强制重新渲染会使document
的更新成员呈现,即使它们在调用setDocument
时没有。
使用new Document()
创建一个新对象并将其传递setDocument
将触发重新渲染。所以我认为 react 没有进行深入比较,或者看到对Document
对象的引用没有改变,因此没有重新重新转换。
那么,是否可以更改对象的成员,将该对象传递给 setState 挂钩并让它更新 UI,而无需创建全新的对象?还是我应该避免做我在这里想做的事情?
你可以(但可能不应该,见下文)使用构造函数创建的对象(这就是代码中的document
)作为状态。你不能做的是直接修改它,就像你在这里一样(见文档):
document.title = 'Some Default Title'; // <=== INCORRECT
document.body = 'lorem text'; // <=== INCORRECT
document.syncWithDatabase();
setDocument(document); // <=== INCORRECT
相反,您需要创建一个新的文档对象
const newDoc = new Document();
newDoc.title = 'Some Default Title';
newDoc.body = 'lorem text';
newDoc.syncWithDatabase();
setDocument(newDoc);
也就是说,当使用useState
钩子时,通常最好保持状态变量离散(一个用于title
,一个用于body
),这样更改一个不需要也更改另一个(当然,除非它们总是一起更改)。文档在此处对此进行了讨论;这里有一句话:
。我们建议根据这些值倾向于一起变化将状态拆分为多个状态变量。
(他们的强调)