首页 > 解决方案 > 在反应状态下使用类实例

问题描述

我有一堂课

class Booper{
  constructor(){
    this.boops = 0;
  }
}

以及使用此类来维护某些状态的反应组件

import React, {useState} from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  const [booper, setBooper] = useState(new Booper());

  const handleClick = () => {
    booper.boops = booper.boops+1;
    setBooper(booper);
  }
  return (
    <div>
      {booper.boops}<br/>
      <button onClick={handleClick}>
        Boop? :(
      </button><br/>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector("#root"))

但是,当我单击按钮时,反应似乎不会触发重新绘制。

如果我添加以下内容,它确实有效。

const App = () => {
  ...

  const clone = (original) => {
    return Object.assign(Object.create(Object.getPrototypeOf(original)), original)
  }

  const handleClickWithClone = () => {
    const cloned = clone(booper)
    cloned.boops = cloned.boops+1
    setBooper(cloned);
  }

  ...

  return (
    <div>
      ...
      <button onClick={handleClickWithClone}>
        Boop! :)
      </button><br/>
    </div>
  )
}

但是,我不完全确定这是要走的路。我不知道垃圾收集器是否会清理所有克隆的对象。或者,如果此解决方案存在其他性能问题。

有没有更好的方法在反应状态中使用类实例?

(完整的小提琴:https ://jsfiddle.net/ho6fka1x/2/ )

标签: javascriptreactjs

解决方案


您正在直接改变状态,这不会导致重新渲染。

这应该工作

const handleClick = () => {
    // booper.boops = booper.boops + 1; //<---remove this
    setBooper(prev => ({...prev, boops: prev.boops + 1}));
  };

推荐阅读