【问题标题】:Fast Refresh + Update function implementation of object that is in React stateReact状态对象的快速刷新+更新函数实现
【发布时间】:2020-10-01 16:15:27
【问题描述】:

假设我有一个 React 应用程序,它有一个内部状态,我在其中存储一个对象,例如

  const [car, setCar] = useState(new Car());

假设我的班级 Car 如下所示:

class Car {
  constructor(brand) {
    this.carname = brand;
  }

  present() {
    return "I have a " + this.carname;
  }
}

当我运行和调试应用程序时,我可以将 Car 对象保存到状态中并检索它并调用 present()。

现在,当我对 present() 函数进行更改时,例如

  present() {
    return "I have a " + this.carname + " and it is shiny";
  }

然后由于快速刷新我的应用程序得到刷新。但是很遗憾,因为对象已经保存了state,所以它不会收到函数实现的更新。

有没有一种方法可以更改代码,以便通过快速刷新功能实现也将针对处于 React 状态的对象进行更新?

我尝试通过原型更新方法,但也没有用。

【问题讨论】:

    标签: javascript reactjs fast-refresh


    【解决方案1】:

    这实际上有点棘手,因为您试图实现的目标与 react 围绕不可变的设计有些背道而驰。使用Object.setPrototypeOf(car, Car.prototype) 可以轻松地直接更改类方法并将其分配给现有实例。

    这替换了原始汽车实例的原型并更改了方法实现。正如你所说,这不起作用,因为改变对象不会触发重新渲染。

    useState 使用 Object.is() 比较对象,在这种情况下不会触发重新渲染,因为两个对象具有相同的引用。

    为了Object.is(),您需要将具有新原型和现有实例的确切属性的新对象传递给setCar()。这不能使用基本扩展运算符{..car}Object.assign({}, car) 来完成,因为这些方法只复制对象自己的可枚举属性。

    您可以改用以下内容来创建一个具有与新原型 setCar(Object.assign(Object.create(Car.prototype), car)) 完全相同的属性的新对象

    这可以放在 useEffect 中,每次更改原始 Car 类时都会运行

     const [car, setCar] = useState(new Car());
    
     useEffect(() => {
        setCar(Object.assign(Object.create(Car.prototype), car))
      }, [])
    

    【讨论】:

      【解决方案2】:

      根据设计,快速刷新将尽可能保留状态。然而,无论依赖数组中有什么,useEffect 都会在快速刷新期间更新。只要你提供一个空的依赖数组,你就可以在 useEffect 中使用 setState 来改变快速刷新之间的状态。

       const [car, setCar] = useState(new Car());
      
       useEffect(() => {
          setCar(new Car());
        },[])
      
      

      但请记住,useEffect 只会在第一次渲染后运行,因此您需要在 useState 挂钩参数中保持默认状态 new Car() 以防止出现任何未定义的错误。

      【讨论】:

      • 是的,我可以执行一些代码,这些代码将在快速刷新后执行。但这会用一个全新的对象替换我的状态吗?有没有办法保留对象但只更新来自代码更改的所有方法实现?
      猜你喜欢
      • 2020-05-26
      • 2018-09-08
      • 2018-03-20
      • 2016-10-06
      • 2020-03-07
      • 1970-01-01
      • 2020-10-21
      • 2015-11-01
      • 1970-01-01
      相关资源
      最近更新 更多