ES6类应该直接用作React状态吗?
我想定义一个ES6类:
但是,至少就我所知,调用setState
在diff类成员中似乎没有。
使用以下课程:
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>
);
}
单击第一个按钮将在Document
保持反应状态的实例上设置标题和正文,但不会更新UI。
单击第二个按钮以我确信会起作用的方式强制进行重新渲染,使document
的更新成员得以渲染,即使在调用setDocument
时没有更新。
使用new Document()
创建新对象并将其传递给setDocument
WILL会触发重新渲染。因此,我认为react并没有进行深度比较,或者看到对Document
对象的引用没有更改,因此没有重新发送。
因此,是否可以更改对象的成员,将该对象传递给setState挂钩并使其更新UI,而无需创建全新的对象?还是应该避免做我想在这里做的事情?
您可以(但可能不应该,请参见下文)使用由构造函数创建的对象(这是您的代码中的document
)作为状态。您做不到的操作是直接在此处进行修改(请参见the documentation):
document.title = 'Some Default Title'; // <=== INCORRECT
document.body = 'lorem text'; // <=== INCORRECT
document.syncWithDatabase();
setDocument(document); // <=== INCORRECT
相反,您需要创建一个new文档对象
const newDoc = new Document();
newDoc.title = 'Some Default Title';
newDoc.body = 'lorem text';
newDoc.syncWithDatabase();
setDocument(newDoc);
就是说,使用 我们建议根据状态值一起变化将状态分为多个状态变量。useState
钩子时,通常最好保持状态变量离散(对于title
具有一个变量,对于body
具有一个变量),因此,改变一个变量不需要改变其他(当然,除非它们总是一起改变)。该文档讨论了here。这是一个报价:...
((他们的重点)