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

Storing an object in state of a React component?

本文关键字:状态 组件 React 对象 存储      更新时间:2023-09-26

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

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

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

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

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

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

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

  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

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

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

除了kiran的帖子之外,还有更新助手(以前是一个反应插件)。这可以使用 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
}

更新这个答案已经很多年了,现在已经过时了。

  1. 如果你试图进行深度更新,你可能应该使用钩子和/或重构你的代码。
  2. 您可能应该使用带有useState钩或减速器的功能组件。
  3. 我为历史背景保留了这个答案。
<小时 />

这里之外是龙!

<小时 />

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 spread/rest 运算符直接复制:

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

在一行代码中完成此操作的更简单方法

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

即使可以通过不可变性助手或类似工具完成,除非我真的必须这样做,否则我不想在我的代码中添加外部依赖项。当我需要这样做时,我使用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'})})}

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

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;

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

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

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