保存状态中的对象数组 - ReactJS

Posted

技术标签:

【中文标题】保存状态中的对象数组 - ReactJS【英文标题】:Save array of objects in state - ReactJS 【发布时间】:2017-04-25 18:29:40 【问题描述】:

我正在构建一个 ReactJS 应用程序,我需要以这种方式存储数据:

this.state = 
    user: 
        name: "",
        surname: "",
        age: "",
        ...
        instruments: [],
    

instruments 状态需要包含多个对象,属性为nameexperience。一个例子:

instruments: [
    
        name: 'Bass guitar',
        experience: 7,
    ,
    
        name: 'Drums',
        experience: 1,
    
    ...
]

我是 React 新手,到目前为止,我已经能够通过这样做将数据保存在类似的数组中:

musicListenChange(val)
        let musicListenArray = this.state.user.music_listen ? this.state.user.music_listen : [];
        musicListenArray.push(val.value);
        this.setState(user: ...this.state.user, music_listen: musicListenArray);
    

但是,当我尝试使用以下代码保存对象时,我收到一个错误:

saveInstrument()
        // save current instruments state in array, or create an empty one 
        let array = this.state.user.instruments ? this.state.user.instruments : [];

        // in this.state.instruments I saved a temporary copy of the selected instrument, put it in the array
        array.push(this.state.instruments);
        this.setState(user: ...this.state.user, instruments: array );
        console.log('instrum. state: ', this.state.user.instruments);
    

错误代码

Uncaught Error: Objects are not valid as a React child (found: object with keys name, experience). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `EditProfile`.

我的 EditProfile 乐器渲染部分

<div className="container-tags">
    this.state.user.instruments ? this.state.user.instruments.map(function (instrument, index) 
        return <button className="btn btn-default">instrument</button>;
    ) : <div></div>
</div>

关于如何解决这个问题的任何想法?谢谢

【问题讨论】:

this.state.instruments 里面有什么? 在 this.state.instruments 我保存 name: "string", experience:"string" 【参考方案1】:

Instrument 是一个对象,您正在尝试渲染它,使用您要渲染的特定值,试试这个:

musicListenChange(val)
    let user = this.state.user;  
    user['music_listen'] = val.value;
    this.setState(user: user);


saveInstrument()
    let user = this.state.user;
    user['instruments'] = user['instruments'] ? user['instruments'] : [];
    user['instruments'].push(this.state.instruments);
    this.setState(user: user);

在渲染函数中使用这个:

this.state.user.instruments ? 
     this.state.user.instruments.map((instrument, index) => 
        return (<button className="btn btn-default">instrument.name</button>)
     )
:<div/>

【讨论】:

this.state.instruments 实际上不是一个数组,它是一个对象。所以我认为问题不存在.. 但感谢您的尝试 如果 this.state.instrument 是一个对象,那么你如何在 html 中使用 instrument,如何打印一个对象。 我做了一些更改,请检查。 @TheCondor 你一定很困惑,this.state.instruments 肯定是一个数组,因为你像instruments: [] 一样定义它,然后对其进行数组操作,例如pushmap。这是一个对象数组。 我会说这被认为是一种不好的做法。每次使用 setState() 更改状态时,必须重新创建 user 的新对象,例如const user = ...this.state.user 在更改user 之前,然后您可以对user 进行更改,最后调用setState(user)。这样,您的状态也可以与纯组件一起使用,否则它们将不会重新呈现。【参考方案2】:

问题出在这里:

<div className="container-tags">
    this.state.user.instruments ? this.state.user.instruments.map(function (instrument, index) 
        return <button className="btn btn-default">instrument</button>;
    ) : <div></div>
</div>

当意识到 instrument 是一个 javascript 对象(您说您的 instruments 数组包含具有结构 name: "string", experience:"string" 的对象)时,错误消息变得清晰:您正在尝试插入一个对象作为 @ 的子对象987654325@ 元素,这是不允许的,因为 React 不知道如何显示对象。如果您使用 instrument.nameinstrument.experience 代替(它们是字符串),您的代码将起作用。

【讨论】:

完美,这就是问题所在!但是其他用户之前回复并提出了相同的解决方案,因此我给了他正确的答案。谢谢!

以上是关于保存状态中的对象数组 - ReactJS的主要内容,如果未能解决你的问题,请参考以下文章

Reactjs如何在状态中初始化数组对象

如何在 Reactjs 中的状态对象内将值添加到数组中

单击事件后如何从 ReactJS 中的数组中删除对象

ReactJS如何更新数组中对象的状态

如何从 Reactjs 中的 useEffect 挂钩访问道具

从存储在 React 状态中的对象数组访问属性