如何将对象从Firebase查询推入this.state

时间:2019-11-15 13:47:59

标签: javascript reactjs firebase firebase-realtime-database

我已从Firebase提取数据。数据在那里,正如console.log确认的那样。

(2) [{…}, {…}]
0:
id: 1.417253735436239
name: {Jack: true}
__proto__: Object
1:
id: 1.7540006580031215
name: {Jack: true, Jill: true}
__proto__: Object
length: 2

但是,我需要遍历此数据以列出名称,但是当我尝试将此数据setState到一个数组中(在构造函数中明确声明)时,我无法获取未定义的属性“ setState”。

这是带有setList函数的代码不起作用:

let users = [];
      listRef.on("value", function (snapshot) {
        users.push({
          id: 1 + Math.random(),
          name: snapshot.val()
        })
        console.log(users);
      });
      function setList(users){
        this.setState({ names: users})
      }
      setList();
    });
  }

名称在构造函数的this.state中声明为数组。

我要去哪里错了?

2 个答案:

答案 0 :(得分:1)

我克服了错误。在块内部使用函数是错误的。我将setState从大括号中移出并且没有该功能。

 setName = e => {
    e.preventDefault()
    this.setState({ [e.target.name]: e.target.value })
    let textBox = document.getElementById('inputDivId');
    textBox.style.display = "flex";
    let messagesBox = document.getElementById('messagesDivId');
    messagesBox.style.display = "flex";
    let thinkDel = document.getElementById('options');
    thinkDel.style.display = "flex";
    let nameBox = document.getElementById('nameDivId');
    nameBox.style.display = "none";

    // Add ourselves to presence list when online.
    let name = this.state.name;
    // let names = this.state.names;
    let connectedRef = firebase.database().ref('.info/connected');

    // let users = [];
    connectedRef.on('value', function (snap) {
      if (snap.val() === true) {
        const con = listRef.child(name);
        con.onDisconnect().remove();
        con.set(true);
      }

      let users = [];
      listRef.on("value", function (snapshot) {
        users.push({
          id: 1 + Math.random(),
          name: snapshot.val()
        })
        setList(users);
      });

      function setList(users) {
        this.setState({
          names: users
        })
      }
    });
  }

但是我仍然无法根据需要在this.state.names中获取数据!

答案 1 :(得分:0)

从Firebase异步加载数据。加载数据后,主代码继续运行。然后,当数据可用时,将调用您的回调。

最简单的方法是放置一些日志语句:

console.log("Before attaching listener");
listRef.on("value", function (snapshot) {
  console.log("Got data");
});
console.log("After attaching listener");

运行此代码时,它将记录:

  

在附加侦听器之前

     

附加监听器后

     

获得数据

这可能不是您期望的,但实际上是定义的行为。并且它还解释了为什么代码无法正常工作:在您调用this.setState({ names: users })时,您的回调尚未运行,并且users为空。

由于这个原因,任何需要数据库中数据的代码都必须在回调内部 或从那里调用。对于ReactJS,这非常简单:您只需在回调中调用setState

let users = [];
listRef.on("value", function(snapshot) {
    users.push({
        id: 1 + Math.random(),
        name: snapshot.val()
    })
    setList(users);
});

function setList(users) {
    this.setState({
        names: users
    })
}

我不确定listRef的数据结构是什么样子,但是怀疑您实际上是在寻找它:

listRef.on("value", function(snapshot) {
  let users = [];
  snapshot.forEach(function(user) {
    users.push({
        id: snapshot.key,
        name: snapshot.val()
    })
  });
  setList(users);
});
相关问题