【问题标题】:how to setState an array which is nested inside an array of objects如何设置嵌套在对象数组中的数组
【发布时间】:2020-11-08 07:36:31
【问题描述】:

这是我的状态

this.state = {
    notification: [{
            from: {
                id: someid,
                name: somename
            },
            message: [somemessage]
        },
        {..},
        {..},
    ]
}

现在,如果我从 someid 收到一条新消息,我必须将该新消息推送到 someid

message 数组中

我尝试以不同的方式推送该消息,但没有任何效果

我尝试过这种方式,但我无法将新消息推送到 message 数组中

if (this.state.notification) {
    for (let q = 0; q < this.state.notification.length; q++) {
        if (
            this.state.notification[q] &&
            this.state.notification[q].from &&
            this.state.notification[q].from.id === r.from.id
        ) {
            this.setState({
                notification: [
                    ...this.state.notification[q].messages,
                    this.state.notification[q].messages.push(r.message),
                ],
            });
            return console.log(this.state.notification[q].messages)
        }
    }
} else {
    this.setState({
        notification: [{
            from: r.from,
            messages: [r.message]
        }, ]
    });
    return console.log(JSON.stringify(this.state.notification));
}

【问题讨论】:

    标签: javascript reactjs state setstate


    【解决方案1】:

    首先,我认为将您的状态构造为二维数组并不是一个好主意。不过你可以试试这个

    const pushMessage = (someId, someMessage) => {
      this.setState({
        notifications: this.state.notifications.map((notification) => {
          if (notification.from.id === someId) {
            return {
              ...notification,
              messages: [...notification.messages, someMessage],
            };
          }
          return notification;
        }),
      });
    };
    

    【讨论】:

      【解决方案2】:

      我很确定你不能这样做:this.state.notification[q].messages.push(r.message)。你不能直接改变你的状态。你应该使用你的状态的副本,用你的代码修改它似乎没问题,然后执行setState(...)

      Here is a repro on Stackblitz 有效。这是代码:

      import React, { Component } from "react";
      import { render } from "react-dom";
      import "./style.css";
      
      class App extends Component {
        constructor() {
          super();
          this.state = {
            notifications: [
              {
                from: { id: 0, name: "Quentin" },
                message: ["Message 1"]
              },
              {
                from: { id: 1, name: "John" },
                message: ["Message 1"]
              },
              {
                from: { id: 2, name: "Henry" },
                message: ["Message 1"]
              }
            ]
          };
      
          this.pushMessage = this.pushMessage.bind(this);
        }
      
        pushMessage (id, message) {
          const newState = Object.assign([], this.state);
          newState.notifications.forEach(notif => {
            if (notif.from.id === id) {
              notif.message.push(message);
            }
          });
      
          this.setState(newState, () => console.log(this.state));
        };
      
        render() {
          return (
            <div>
              <button onClick={() => this.pushMessage(1, "Hello World")}>
                Push message
              </button>
            </div>
          );
        }
      }
      
      render(<App />, document.getElementById("root"));
      
      

      我只处理现有通知中消息的推送,你已经得到了另一种情况。

      【讨论】:

      • 这是一个例子,我尝试以不同的方式推送消息,但没有任何效果,它使通知为空
      • @sairam 我编辑了我的答案给你一个有效的例子
      【解决方案3】:

      setState 的第一个参数是一个更新函数,它将先前的状态作为参数。我认为你应该利用这个事实来正确地更新你的状态。

      看看这个答案https://medium.com/@baphemot/understanding-reactjs-setstate-a4640451865b

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-10
        • 2022-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-11
        • 2021-08-02
        相关资源
        最近更新 更多