【问题标题】:Accessing index of an array returns undefined访问数组的索引返回未定义
【发布时间】:2020-07-16 13:03:42
【问题描述】:

我正在构建一个简单的 React 应用程序,在其中我从 Firebase 实时数据库收集数据并通过 setState 将其作为数组 (memberArr) 推送到组件状态:

this.setState({members: memberArr})

当我在 render() 方法中记录状态时,我看到了数组的内容。在 React 开发工具中,状态也按预期填充。

如果我现在想访问数组的内容(例如,使用 this.state.members[0]),控制台会返回 undefined。

我这样初始化状态:

constructor(props) {
  super(props);
  this.state = {
      members: [],
  };
}

我的整个 componentDidMount() 方法如下所示:

componentDidMount() {

    const membersRef = firebase.database().ref(`${groupName}/members`);

    membersRef.on('value', (data) => {

      const memberArr = []; 

      data.forEach(function(snapshot){

        //Gets name of member
        var memberName = snapshot.val().name;

        //Gets UID of member
        var memberKey = snapshot.key;

        //Get expenses from fetched member. When ready call function to push everything as array into component state.
        this.getExpensesFromUser(memberKey).then(function(data) {
          pushArray(data)
        });

        function pushArray(memberExpense) {
          memberArr.push([memberName, memberKey, memberExpense])
        };

        //This works:
        //memberArr.push([memberName, memberKey])

      }.bind(this));

      this.setState({members: memberArr})

    });
  }

附带说明:如果我避免打电话

this.getExpensesFromUser(memberKey).then(function(data) {
          pushArray(data)
        });

并且仅使用以下方式推送成员的名称和密钥:

memberArr.push([memberName, memberKey])

一切都按预期进行。 console.log(this.state.members[0][0]) 返回由于 setState 触发 render() 方法后的第一个成员的名称。

你有什么建议给我吗?

【问题讨论】:

  • 在渲染时检查数组是否已填充。
  • this.getExpensesFromUser(memberKey) 是异步的,您在实际接收值之前设置状态,因此您的状态始终为 []
  • @DragoşPaulMarinescu 但是为什么我在 React 开发工具中看到了正确的状态内容?此外:如果我在 render() 方法中 console.log 状态,它也会向我显示我期望的内容。
  • 而不是pushArray(data)中的.then(data)尝试做this.setState({members: [...this.state.members, data]
  • 我认为初始化还没有完成。我的意见是使用构造函数来初始化状态,然后填充其数据@你的构造函数或你的 componentDidMount

标签: javascript arrays reactjs firebase


【解决方案1】:

正如 Dragos 所说,您的 getExpensesFromUser 函数会返回异步结果,因此您需要确保仅在这些调用完成后才调用 setState。

const membersRef = firebase.database().ref(`${groupName}/members`);
membersRef.on('value', (data) => {
  const promises = [];
  data.forEach((snapshot) => {
    var memberKey = snapshot.key;
    promises.push(this.getExpensesFromUser(memberKey))
  });

  Promise.all(promises).then((data) => {
    const memberArr = data.map((item) => [memberName, memberKey, memberExpense]);
    this.setState({members: memberArr})
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-17
    • 2018-06-03
    • 2015-10-17
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    相关资源
    最近更新 更多