Javascript ES6 类 应该用作 React 状态吗?

Should Javascript ES6 Classes be Used as React State?

ES6 classes 是否应该直接用作 React 状态?

我想定义一个 ES6 class:

  1. 有成员变量显示在前端。 (对它们的更改触发 re-renders)
  2. 有方法可以在这些成员变量发生变化时定期将它们与我的后端同步。

然而,调用 setState 似乎不会区分 class 成员,至少据我所知。

使用以下 class:

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保持反应状态的实例上设置标题和body,但它不会更新UI。

单击第二个按钮以我确信会起作用的方式强制执行 re-render 会使 document 的更新成员呈现出来,即使它们在 [=17= 时没有呈现] 叫做。

new Document() 创建一个新的 object 并传递它 setDocument 触发 re-render。所以我认为 React 没有进行深入比较,或者看到对 Document object 的引用没有改变,因此 re-rending 没有改变。

那么,是否可以更改 object 的成员,将 object 传递给 setState 挂钩并让它更新 UI,而无需创建全新的 object?或者我应该避免做我想在这里做的事情吗?

可以 (但可能不应该,见下文)使用由构造函数创建的对象(这就是 document 在您的代码中的作用)作为状态。你不能做的是直接修改它(见the documentation):

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),这样改变一个并不需要同时改变另一个(当然,除非它们总是一起改变)。该文档讨论了here;这是一个引用:

...we recommend to split state into multiple state variables based on which values tend to change together.

(他们强调)