将对象存储在 React 组件的状态?

IT技术 javascript reactjs
2021-04-20 16:38:47

是否可以在 React 组件的状态下存储对象?如果是,那么我们如何使用 更改该对象中键的值setState我认为在语法上不允许写这样的东西:

this.setState({ abc.xyz: 'new value' });

在类似的方面,我还有另一个问题:在 React 组件中有一组变量可以在组件的任何方法中使用,而不是将它们存储在状态中吗?

您可以创建一个包含所有这些变量的简单对象并将其放置在组件级别,就像在组件上声明任何方法一样。

很可能会遇到这样的情况:您将大量业务逻辑包含在代码中,并且需要使用许多变量,这些变量的值通过多种方法更改,然后您根据这些值更改组件的状态。

因此,不是将所有这些变量都保留在状态中,而是只保留那些值应该直接反映在 UI 中的变量。

如果这个方法比我在这里写的第一个问题更好,那么我不需要在状态中存储一个对象。

6个回答
  1. this.setState({ abc.xyz: 'new value' });不允许使用语法。你必须传递整个对象。

    this.setState({abc: {xyz: 'new value'}});
    

    如果你在 abc 中有其他变量

    var abc = this.state.abc;
    abc.xyz = 'new value';
    this.setState({abc: abc});
    
  2. 你可以拥有普通变量,如果它们不依赖 this.props 和this.state.

这个答案看起来很可疑,就像 OP 直接修改状态一样,这是一个很大的禁忌。假设abc只有原始字段,正确的第一行应该是var abc = { ...this.state.abc };
2021-05-27 16:38:47
@kiran 将复杂对象设置为变量不会复制它,它只是对同一对象进行另一个引用。所以, var abc = this.state.abc; abc.xyz = 'new value'; 是一样的 this.state.abc.xyz='new value'
2021-05-31 16:38:47
如果你想在对象中保留其他属性,像 underscore's extend这样的方法很有用:this.setState({abc: _.extend(this.state.abc, {xyz: 'new value'})});
2021-06-12 16:38:47
@smhg 不完全update是,它更强大,因为它支持修改状态内部复杂对象的命令当您不需要这些特殊功能时,我认为_.extend提供了更清晰的语法,尤其是对于稍后阅读代码并且不熟悉update.
2021-06-18 16:38:47
@smhg,添加到你的,Object.assign如果你的浏览器支持 ES6 ,你可以使用(或者只使用 polyfill)
2021-06-21 16:38:47

您可以在对象中的先前值上使用ES6 扩展以避免覆盖

this.setState({
     abc: {
            ...this.state.abc,
            xyz: 'new value'
           }
});

除了 kiran 的帖子,还有更新助手(以前是 react 插件)。这可以使用 npm 安装npm install immutability-helper

import update from 'immutability-helper';

var abc = update(this.state.abc, {
   xyz: {$set: 'foo'}
});

this.setState({abc: abc});

这将创建一个具有更新值的新对象,其他属性保持不变。当您需要执行诸如推送到数组之类的操作并同时设置一些其他值时,这会更有用。有些人到处使用它,因为它提供了不变性。

如果这样做,您可以通过以下方式来弥补

shouldComponentUpdate: function(nextProps, nextState){
   return this.state.abc !== nextState.abc; 
   // and compare any props that might cause an update
}
似乎这个助手现在是遗留的,推荐使用这个库:github.com/kolodny/immutability-helper
2021-05-24 16:38:47
因此,我认为将状态存储在除 之外的其他内容中会容易得多this.state,并render()您更改其中的内容时随时调用在有经验的 React 开发人员中,这是否被认为是完全禁忌?
2021-05-26 16:38:47
render 是一个纯函数,它实际上什么也不当有更新时,它会被 react 调用,而更新是由 setState 调用引起的。最佳实践说你的渲染应该为相同的道具和状态产生相同的输出。这也允许像 shouldComponentUpdate 这样的优化变得简单。
2021-06-07 16:38:47
哇,我离开SO这么久了吗?实际上,我最终使用了一些基本的反应式工具来forceUpdate()在 Backbone 模型的给定字段发生变化时进行调用因此,我可以简单地覆盖shouldComponentUpdate以返回 false。render仍然为相同的props“状态”产生相同的输出(即主干模型,我没有在 中存储任何东西this.state)。
2021-06-09 16:38:47
@Sebastianonsorequire('react-addons-update')并安装它。
2021-06-15 16:38:47

this.setState({abc: {xyz: 'new value'}});将不起作用,因为state.abc将被完全覆盖,而不是合并。

这对我有用:

this.setState((previousState) => {
  previousState.abc.xyz = 'blurg';
  return previousState;
});

除非我读错了文档,否则 Facebook 建议使用上述格式。 https://facebook.github.io/react/docs/component-api.html

另外,我想不改变状态的最直接方法是使用 ES6 扩展/休息运算符直接复制:

const newState = { ...this.state.abc }; // deconstruct state.abc into a new object-- effectively making a copy
newState.xyz = 'blurg';
this.setState(newState);
我测试了你的第一种使用方式componentDidUpdate(),它正确地保持了以前的状态,同时this.setState({[abc.xyz]: 'blurg'})给出了不正确的先前状态,所以我认为它很好。
2021-06-05 16:38:47
previousState 实际上并不是previousState。这是当前状态,这是不正确的。
2021-06-10 16:38:47
previousState.abc.xyz = 'blurg'; 改变当前状态,这是 React 中的一种反模式。
2021-06-21 16:38:47

在一行代码中更简单的方法

this.setState({ object: { ...this.state.object, objectVarToChange: newData } })