反应状态下的对象数组不起作用

Posted

技术标签:

【中文标题】反应状态下的对象数组不起作用【英文标题】:React array of objects in state not working 【发布时间】:2018-06-16 00:54:10 【问题描述】:

我目前在使用 Firebase 和使用状态时遇到了一些问题。是的,我想指出我是 React 新手。基本上我想要实现的是显示所有发送给我的inquiries,它们存储在firebase中。

为了实现这一点,我做了以下工作:

constructor(props) 
  super();

  this.fetchMessage = this.fetchMessage.bind(this);
  this.state = 
    messages: []
  ;


fetchMessage = () => 
  const database = firebase.database();
  const inquiries = [];

  database.ref('inquiries').on('value', (snapshot) => 
    snapshot.forEach((childSnapshot) => 
      inquiries.push(
        id: childSnapshot.key,
        fullName: childSnapshot.val().fullName,
        email: childSnapshot.val().email,
        message: childSnapshot.val().message,
        subject: childSnapshot.val().subject,
        dateSent: childSnapshot.val().dateSent
      );
    );
    console.log(inquiries);
    this.setState(() => 
      return 
        messages: inquiries
      
    );
  );

我要做的是将所有inquiries 存储在状态中,以便我可以运行for-loop 并在我的网站上显示所有内容。我该怎么做呢?

我的第一个想法是,如前所述:将每个对象存储在状态中,然后像 this.state.messages[0]this.state.messages[1] 一样访问每个查询(以获取完整数组),然后通过执行 this.state.messages[0].fullName 显示每个值例如。

我怎样才能做到这一点?我目前的错误是:

[Error] Invariant Violation: Objects are not valid as a React child (found: object with keys id, fullName, email, message, subject, dateSent). If you meant to render a collection of children, use an array instead.
    in h1 (created by AdminPanel)
    in div (created by AdminPanel)
    in AdminPanel (created by Route)
    in Route
    in Switch
    in div
    in Router (created by BrowserRouter)
    in BrowserRouter
    (anonymous function) (bundle.js:1530)

【问题讨论】:

你试过'this.setState(messages:inquiries);'代替? @Dream_Cap 还是一样的问题..奇怪.. 您能否添加呈现消息列表的代码。根据您的错误,我猜这就是它的位置 【参考方案1】:

看来问题不在于您的状态,而在于您的渲染方法。

这是您应该在应用中显示消息的方式。

componentDidMount() 
  this.fetchMessage()

render() 
  const  messages  = this.state
  return (
    <div>
      <table>
        messages.map((message) => 
          return (
            <tr key=message.id>
              <td>message.fullName</td>
              <td>message.email</td>
              <td>message.message</td>
              <td>message.subject</td>
              <td>message.dateSent</td>
            </tr>
          )
        )
      </table>
    </div>
  )

【讨论】:

当我使用上面的代码时,这给了我 +999 错误。奇怪的错误,你知道这里可能是什么问题吗? 你怎么打电话给fetchMessage 我实际上是在渲染中调用它,在 const messages = this.state 之上,这样做:'this.fetchMessage();'。我想这是错的? 是的,作为一般规则,您永远不必在 render 方法中调用 setState。因为它会产生一个无限循环。查看我的答案,我已更新。 这太棒了!有效!你知道我可以怎样实现自动化,这样我就不用点击按钮了吗?

以上是关于反应状态下的对象数组不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在循环中推送对象数组中的值?

使用拼接反应本机从数组中删除对象元素

javascript array.includes在反应中不起作用

解析对象数组在 (Nativescript) Vue 中不是反应式的

如何在反应中的对象数组中设置对象数组的状态

如何通过单击按钮从反应状态挂钩数组中删除对象