javascript - 在 ReactJS 中手动刷新 Firebase 对象

标签 javascript reactjs firebase firebase-realtime-database

我有一个小应用程序,用户可以在其中输入一个人的名字并将他们添加到版 block ,然后用户可以对他们投赞成票或反对票(对于梦幻足球)。目前,唯一无需刷新页面即可立即发生的事情是通过文本输入框添加播放器时。这对对象做了一点淡入,它正好出现在屏幕上:

addPlayer(player) {

this.state.user ?
  this.database.push().set({ playerContent: player, votes: 0})
  :
  console.log("Not Logged In")
}

因为是推送所以是实时完成的吗?在用户投票后,我如何让玩家委员会更新?现在,假设 Jane Doe 有两票,而 John Doe 有 2 票,而您将 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.")
}
}

如果我缺少相关代码,请告诉我,我会提供。我尝试在投票后调用 componentDidMountthis.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}
      />
    )
  })
}

编辑

当我将 upvotePlayer 函数的数据库调用更改为 .on 而不是 .once 并继续为播放器投票时,它会喷出无限量的 console.logs来自这个 componentWillMount 函数:

App.js 第 51 行是下面的 console.log。

  this.database.on('child_changed', function (snapshot) {
    var name = snapshot.val();
    console.log("Player: " + name.playerContent + " has  " + name.votes + " votes.")
  })

大约 20 秒后,当它自身重载时,会出现一个错误页面并显示 RangeError: Maximum call stack size exceeded

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

错误:
enter image description here
enter image description here

App.js(投票发生的地方(upvotePlayer))和 Player.jsx 的要点。 Gist with App.js and Player.jsx


编辑2

当我在 comondentDidMount() 的 Player.jsx 文件中从 .once 更改为 .on 时,投票立即开始注册到屏幕,如下所示。澄清一下,这解决了我的投票图标在我从赞成票变为反对票时没有实时变化的问题。我还没有测试它是否像我最初问的那样注册一个玩家以更多的票数超过另一个玩家。只是想为可能查看此代码以帮助自己的任何人澄清。

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(...)

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())
          }

        })

关于javascript - 在 ReactJS 中手动刷新 Firebase 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48575569/

相关文章:

node.js - react : how to load image outside src and public folders

android - 多次调用 FirebaseApp.initializeApp 的缺点是什么?

ionic-framework - 使用 Firebase 通知手动注册设备 token

javascript - js数学方程之谜

javascript - 将 Promise 转换为同步函数

javascript - 如何使用工具栏选项在 Quill js 上添加字体类型?

javascript - 拉伸(stretch)高度以适应 React Native 中的内容

javascript - JQuery 下拉行为

javascript - 为什么 TypeError : Cannot read property '0' of undefined?

java - 在 firebase android 中拯救一个 parent 下的许多 child