Javascript 在ReactJS中手动刷新Firebase对象

Javascript 在ReactJS中手动刷新Firebase对象,javascript,reactjs,firebase,firebase-realtime-database,Javascript,Reactjs,Firebase,Firebase Realtime Database,我有一个小应用程序,用户可以输入一个人的名字,并将他们添加到一个板上,然后用户可以向上或向下投票给他们(对于梦幻足球)。目前,唯一不需要刷新页面就可以立即执行的操作是通过文本输入框添加播放器。这会使对象稍微淡入,并直接显示在屏幕上: addPlayer(player) { this.state.user ? this.database.push().set({ playerContent: player, votes: 0}) : console.log("Not Logged I

我有一个小应用程序,用户可以输入一个人的名字,并将他们添加到一个板上,然后用户可以向上或向下投票给他们(对于梦幻足球)。目前,唯一不需要刷新页面就可以立即执行的操作是通过文本输入框添加播放器。这会使对象稍微淡入,并直接显示在屏幕上:

addPlayer(player) {

this.state.user ?
  this.database.push().set({ playerContent: player, votes: 0})
  :
  console.log("Not Logged In")
}
这是实时完成的吗,因为这是一个推送?在用户投票后,我如何让玩家委员会更新?现在,如果说Jane Doe有两张票,John Doe有两张票,而你最多给John Doe投3张票,他不会跳到Jane Doe前面,直到你刷新页面之后。在投票时,是否有方法刷新每个对象?这是我的投票代码

upvotePlayer(playerId) {
if(this.state.user) {
  let ref = firebase.database().ref('/players/' + playerId + '/voters');

  ref.once('value', snap => {
    var value = snap.val()
    if (value !== null) {            
        ref.child(this.uid).once('value', snap => {
          if (snap.val() === 0 || snap.val() === -1 || snap.val() == null){
            ref.child(this.uid).set(1);
          } else if (snap.val() === 1) {
          ref.child(this.uid).set(0);
          }
          else {
            console.log("Error in upvoting. snap.val(): " + snap.val())
          }

        })

    } else {
        console.log("Doesn't exist")
        ref.child(this.uid).set(1);
    }
});
}
else {
    console.log("Must be logged in to vote.")
}
}
如果我缺少相关代码,请让我知道,我会提供它。我试着在投票后调用
componentDidMount
,然后调用
this.forceUpdate()
(即使不鼓励这样做),只是想看看这是否是一个解决方案,但它似乎不是

这是在App.js中呈现的播放器组件

{
  orderedPlayersUp.map((player) => {
    return (
      <Player
        playerContent={player.playerContent}
        playerId={player.id}
        key={player.id}
        upvotePlayer={this.upvotePlayer}
        downvotePlayer={this.downvotePlayer}
        userLogIn={this.userLogIn}
        userLogOut={this.userLogOut}
        uid={this.uid}
      />
    )
  })
}
大约20秒后,当它自身过载时,会出现一个错误页面,显示
RangeError:Maximum call stack size Oversed

将componentWillMount函数数据库调用更改为
this.database.once
而不是
.on
会减少无限循环,但仍会抛出
RangeError:超过最大调用堆栈大小

错误:

关于App.js(投票发生的地方(upvotePlayer))和Player.jsx的要点


编辑2 当我在comondentdimount()中的Player.jsx文件中将
.one
更改为
.on
时,投票立即开始注册到屏幕上,如下所示。澄清一下,这解决了当我从upvote更改为downvote时,投票图标不会实时更改的问题。我还没有测试它是否像我最初要求的那样,一名球员以更多的选票超越另一名球员。我只是想澄清一下,任何人都可以通过这些代码来帮助自己

componentDidMount() {
  let ref = firebase.database().ref('/players/' + this.playerId + '/voters');

  ref.on('value', snap => {
    var value = snap.val()

    if (value !== null && this.props.uid !== null) {       
        ref.child(this.props.uid).on('value', snap => {
          if (snap.val() === 1){
            this.setState({ votedUp: true, votedDown: false })
            }
          else if (snap.val() === 0) {
            this.setState({ votedUp: false, votedDown: false })
          }
          else if (snap.val() === -1) {
            this.setState({ votedDown: true, votedUp: false })
          }
          else {
          console.log("Error calculating the vote.")
          }
        })
    } else {
      //Error
    }
});

  }

您的firebase调用目前是.once()调用。这将只调用数据库一次。如果希望组件继续侦听更改,则需要切换到.on()调用。所以这将是
ref.child(this.uid).on(…)
而不是
ref.child(this.uid).once(…)


我明白了-谢谢你的澄清。这正是我需要它做的,在查看了您在另一个线程中发布的文档后,这是有意义的。然而,当我在upvote函数中更改为
。on
时,我似乎得到了一个无限循环类型的错误。我用编辑更新了我原来的帖子。再次感谢你提供的信息。你能给我更多关于错误的细节吗。它说什么?如果错误也发生在.once()上,那么这个错误与这个问题无关。也就是说,如果你删除了播放器组件上的up和downvote onClick处理程序,堆栈是否会停止溢出?我找到了答案,并将更改后的代码添加到了原始帖子的底部。正如您所说,我需要从
.one
更改为
.on
,但我是在“Player.jsx componentDidMount()函数”中完成的,它似乎使投票立即注册到屏幕上。再次感谢你的帮助Josh
componentDidMount() {
  let ref = firebase.database().ref('/players/' + this.playerId + '/voters');

  ref.on('value', snap => {
    var value = snap.val()

    if (value !== null && this.props.uid !== null) {       
        ref.child(this.props.uid).on('value', snap => {
          if (snap.val() === 1){
            this.setState({ votedUp: true, votedDown: false })
            }
          else if (snap.val() === 0) {
            this.setState({ votedUp: false, votedDown: false })
          }
          else if (snap.val() === -1) {
            this.setState({ votedDown: true, votedUp: false })
          }
          else {
          console.log("Error calculating the vote.")
          }
        })
    } else {
      //Error
    }
});

  }
ref.child(this.uid).on('value', snap => {
          if (snap.val() === 0 || snap.val() === -1 || snap.val() == null){
            ref.child(this.uid).set(1);
          } else if (snap.val() === 1) {
          ref.child(this.uid).set(0);
          }
          else {
            console.log("Error in upvoting. snap.val(): " + snap.val())
          }

        })