是否有一种反应方式可以将可变类实例对象存储在状态中?

Posted

技术标签:

【中文标题】是否有一种反应方式可以将可变类实例对象存储在状态中?【英文标题】:Is there a react way to store a mutable class instance objects in state? 【发布时间】:2021-05-09 18:27:00 【问题描述】:

不应直接改变 React 状态。但是,如果状态是一个类的实例,它应该可以通过自己的方法进行更改。除了必须使用新参数深度克隆和重新实例化对象之外,还有其他方法吗?

一般来说:在父组件中创建的类对象在子组件中使用同时保持其属性在父状态(通过 props/context 传递)的反应方式是什么?

示例类

class Car
    constructor(data)
        this.data = data
    
    changeColor = (newcolor) => this.data.color = newcolor

示例父组件

const App = (data) => 
 const [car, setCar] = useState(new Car(data))
  return (
    <div>
      <CarViewer car=car />
    </div>
  );
;

示例子组件

const CarViewer = (car) => 
  return (
    <div>
      The color is: car.data.color
    <button onClick=()=>car.changeColor("blue")>Change color to blue </button>
    </div>
  );
;

【问题讨论】:

这方面的实际例子是什么? 我认为这对于在有状态类实例中有一组方法和相应属性的任何用例都是实用的。示例:使用内置缓存函数获取数据并有权访问 window.location.state 的类。它通过 context/props 传递给使用此实例的其他组件。我认为 OOP 可以是一种很好的方法(无论是类还是原型注释),它可以为您的应用程序带来秩序,并问自己当实例是有状态时是否可以以“反应方式”使用它。 我发现这很有用***.com/questions/51831824/… 【参考方案1】:

我认为您需要做的是改变您将类存储在反应状态中的心理模型,并尝试像这样的不同模型,这种模型更具反应方式:

const CarViewer = ( carData, changeColor ) => 
  return (
    <div>
      The color is: carData.color
      <button onClick=() => changeColor("blue")>Change color to blue</button>
    </div>
  );
;

const App = ( data ) => 
  const [carData, setCarData] = useState(data);

  const changeColor = (newcolor) =>
    setCarData((data) => ( ...data, color: newcolor ));

  return (
    <div>
      <CarViewer carData=carData changeColor=changeColor />
    </div>
  );
;

编辑:根据您的评论,我认为您需要的是这样的自定义钩子:


const App = ( data ) => 
  const  carData, changeColor  = useCar(data);
  
  return (
    <div>
      <CarViewer carData=carData changeColor=changeColor />
    </div>
  );
;

function useCar(defaultData = ) 
  const [carData, setCarData] = useState(defaultData);

  const changeColor = (newcolor) =>
    setCarData((data) => ( ...data, color: newcolor ));

  return 
    carData,
    changeColor,
    //... your other methods
  ;

【讨论】:

好吧,想象一下 Car 类是一个更复杂的类,有几十个方法和自己的属性,并且该类应该在其他地方重用.. @elMeroMero 这正是custom hooks 出现的地方 @elMeroMero 再次检查答案,我已经编辑过了 谢谢,我喜欢这种方法。但我仍然问自己,是否有一种“反应方式”来处理有状态的类实例/使用类语法,而不在每个更改其属性的类方法中使用 setState 处理程序? 是否有一种“反应方式”来处理有状态的类实例/使用类语法”简单的答案是“否”,因为 React 不知道内部更改Car 对象并且不会在应该重新渲染 CarViewer 时。当你调用useState(new Car(data)) 时,你的状态只是存储一个对Car 对象的reference。只要引用保持不变,组件就不会更新。因此,您需要 Car 的方法返回一个新实例,然后将 setState 与新实例一起返回。

以上是关于是否有一种反应方式可以将可变类实例对象存储在状态中?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 属性

Class的实例是不可变的吗?

序列化的方式都有哪些

集合框架

并发编程之线程安全性

原型OO:扩展一个不像“类”的对象