Должны ли классы 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
удерживается реагирующее состояние, но не будет обновлять пользовательский интерфейс.
Нажатие второй кнопки для принудительного повторного рендеринга, которое, я уверен, сработает, приводит к обновлению членов document
, даже если они не вызывались при вызове setDocument
.
Создание нового объекта с new Document()
и передача его setDocument
WILL вызывает повторную визуализацию. Так что я думаю, что реакция не делает глубокого сравнения или видит, что ссылка на объект Document
не изменилась, и, следовательно, не повторно отображает.
Итак, возможно ли изменить члены объекта, передать этот объект в хук setState и обновить его пользовательский интерфейс, не создавая совершенно новый объект? Или я должен избегать делать то, что я пытаюсь сделать здесь?