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

时间:2014-11-24 12:48:46

标签: javascript reactjs

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

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

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

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

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

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

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

8 个答案:

答案 0 :(得分:80)

  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,你可以拥有普通变量。

答案 1 :(得分:30)

除了kiran的帖子,还有update helper(以前为a react addon)。这可以使用npm install immutability-helper

与npm一起安装
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
}

答案 2 :(得分:26)

您可以对对象中的先前值使用ES6 spread以避免覆盖

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

答案 3 :(得分:14)

Exception in thread "main" java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class stream.CollectCollector at stream.CollectCollector.lambda$main$0(CollectCollector.java:25) 将无效,因为this.setState({abc: {xyz: 'new value'}});将被完全覆盖,而不会合并。

这对我有用:

state.abc

除非我正在阅读文档错误,否则Facebook会推荐以上格式。 https://facebook.github.io/react/docs/component-api.html

此外,我想没有变异状态的最直接的方法是使用ES6传播/休息算子直接复制:

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

答案 4 :(得分:5)

尽管可以通过immutability-helper或类似方法完成,但我不想在我的代码中添加外部依赖项,除非我真的需要。当我需要这样做时,我使用Object.assign。代码:

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

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

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

答案 5 :(得分:3)

在一行代码中更容易实现

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

答案 6 :(得分:1)

如果您想使用功能组件将对象存储在状态中,您可以尝试以下操作。

import React from 'react';
import {useState, useEffect} from 'react';

const ObjectState= () => {
    const [username, setUsername] =  useState({});

    const usernameSet = () => {
        const name = {
            firstname: 'Naruto',
            familyname: 'Uzmaki' 
        }
        setUsername(prevState => name);
    }

    return(
        <React.Fragment>
            <button onClick= {usernameSet}>
                Store Object
            </button>
           {username.firstname} {username.familyname} 
        </React.Fragment>
    )
}

export default ObjectState;

如果要将对象添加到预先存在的对象中。

import React from 'react';
import {useState, useEffect} from 'react';

const ObjectState= () => {
    const [username, setUsername] =  useState({village: 'Konoha'});

    const usernameSet = () => {
        setUsername((prevState) => {
            const data = {
                ...prevState, 
                firstname: 'Naruto',
                familyname: 'Uzmaki' 
            }
            return data
        });
    }

    return(
        <React.Fragment>
            <button onClick= {usernameSet}>
                Store Object
            </button>
            {username.village} {username.firstname} {username.familyname} 
        </React.Fragment>
    )
}

export default ObjectState;

P.S. :将组件命名为“对象”会导致“最大调用堆栈大小” 超出错误'。其他名称很好,但出于某种原因,“对象”是 不是。 像下面这样不行。

    const Object = () => {
        // The above code
    };

    export default Object;

如果有人知道为什么或如何阻止它,请将其添加到评论中。

答案 7 :(得分:-5)

它对我有用。

_onPress = () => {
    this.state.abc.xyz = "new value";
    this.setState({});
}

编辑:

_onPress = () => {
   let newValue = this.state.abc
   newValue.xyz = "new value"
   this.setState({abc: newValue });
}