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

Rah*_*ole 66 javascript reactjs

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

this.setState({ abc.xyz: 'new value' });
Run Code Online (Sandbox Code Playgroud)

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

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

它很可能遇到这样的情况,即在代码中包含大量业务逻辑,并且需要使用许多变量,这些变量的值由多个方法更改,然后根据这些值更改组件的状态.

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

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

kir*_*ran 86

  1. this.setState({ abc.xyz: 'new value' });语法是不允许的.你必须传递整个对象.

    this.setState({abc: {xyz: 'new value'}});
    
    Run Code Online (Sandbox Code Playgroud)

    如果你在abc中有其他变量

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

  • 如果你想在对象中保留其他属性,像下划线的[extend](http://underscorejs.org/#extend)这样的方法很有用:`this.setState({abc:_.extend(this.state.abc) ,{xyz:'new value'})});` (12认同)
  • 这个答案看起来很可疑,就像 OP 直接修改状态一样,这是一个很大的禁忌。假设 `abc` 只有原始字段,正确的第一行应该是 `var abc = { ...this.state.abc };` (3认同)
  • @smhg,如果你的浏览器支持ES6(或者只是使用polyfill),你可以使用`Object.assign`来添加你的. (2认同)
  • @kiran 将复杂对象设置为变量不会复制它,它只是对同一对象进行另一个引用。所以,`var abc = this.state.abc; abc.xyz = '新值';` 与 `this.state.abc.xyz='新值'` 相同 (2认同)

Bri*_*and 33

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

import update from 'immutability-helper';

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

this.setState({abc: abc});
Run Code Online (Sandbox Code Playgroud)

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

如果这样做,您可以使用以下内容来弥补性能

shouldComponentUpdate: function(nextProps, nextState){
   return this.state.abc !== nextState.abc; 
   // and compare any props that might cause an update
}
Run Code Online (Sandbox Code Playgroud)

  • 看来这个助手现在已经是遗留的,推荐使用这个库:https://github.com/kolodny/immutability-helper (2认同)

Pra*_*ayi 32

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

this.setState({
     abc: {
            ...this.state.abc,
            xyz: 'new value'
           }
});
Run Code Online (Sandbox Code Playgroud)


jas*_*ara 15

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

这对我有用:

this.setState((previousState) => {
  previousState.abc.xyz = 'blurg';
  return previousState;
});
Run Code Online (Sandbox Code Playgroud)

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

另外,我想没有变异状态的最直接的方法是使用ES6 spread/rest运算符直接复制:

const newState = { ...this.state.abc }; // deconstruct state.abc into a new object-- effectively making a copy
newState.xyz = 'blurg';
this.setState(newState);
Run Code Online (Sandbox Code Playgroud)

  • `previousState.abc.xyz = 'blurg';` 改变当前状态,这是 React 中的反模式。 (2认同)

Kev*_*ski 9

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

this.setState({ object: { ...this.state.object, objectVarToChange: newData } })
Run Code Online (Sandbox Code Playgroud)


Ogg*_*las 5

即使可以通过不可变性帮助程序或类似方法完成,但除非确实需要,否则我不会在代码中添加外部依赖项。当我需要做时,我使用Object.assign。码:

this.setState({ abc : Object.assign({}, this.state.abc , {xyz: 'new value'})})
Run Code Online (Sandbox Code Playgroud)

也可以在HTML事件属性上使用,例如:

onChange={e => this.setState({ abc : Object.assign({}, this.state.abc, {xyz : 'new value'})})}
Run Code Online (Sandbox Code Playgroud)