javascript - 如何让我的列表组件在状态更改后呈现?

标签 javascript reactjs firebase components lifecycle

我有一个计算器应用程序,它可以通过 Firebase 实时记录任何用户处理的十个最新方程。每当有人从任何设备基本上点击等号时,它应该会自动更新日志。它在大多数情况下都会这样做,除了用户实际按下等于,在这种情况下,它会延迟一个等式。然而,该用户可以实时查看其他人提交的内容。

我的状态有两个不同的变量。一个称为日志,它是一个在本地保存数据库中所有日志的对象,另一个称为列表,它是一个通过处理日志的函数更新的数组,并按创建时间的顺序获取最近的十个条目。我有一个组件,它映射十个列表以在我的日志组件中创建 li 元素。

这是我的状态和 componentDidMount 方法:

this.state = {
      // input builds a string of user inputs
      input: '',
      // display is for the calculator screen
      display: '...',
      // stores all logs from db
      logs: {},
      // Make a list for 10 recent posts
      list: []
    }
}

  componentDidMount() {
    this.fetchData();
    document.addEventListener("keypress", this.handleKeyPress, true);
  }  

以下是适用于该问题的函数:

  // should fetch data (previous logs) for app on first render,
  // and also update logs live from user and other users
  fetchData = () => {
    // creating reference to root node of firebase db
    const rootRef = firebase.database().ref().child('/logs');
    // on "change" in db, pull all logs
    rootRef.on('value', snapshot => {
      this.setState({
        logs: snapshot.val()
      });
      return this.tenMostRecentLogs(this.state.logs)
    }, function (errorObject) {
      return console.log("The read failed: " + errorObject.code);
    })
  }

// take db object and update app state
  tenMostRecentLogs = obj => {
    // make array of all logs
    const logs = [
      Object.entries(obj)
    ];
    // create array of all logs sorted by timestamp
    const sortedLogs = logs[0].sort((a,b) => (a.timestamp < b.timestamp) ? 1 : -1)
    // create an array of ten most recent posted logs
    let tenLogsSorted = [];
    for (let i=0;i<10;i++) {
      let log = [];
      log.push(sortedLogs[i][1].eq);
      log.push(sortedLogs[i][1].id);
      tenLogsSorted.push(log)
    }
    this.setState({
      list: tenLogsSorted
    })
  }

这是有问题的组件:

<div className='log'>
  <Log logs={this.state.list}/>
</div>

我曾考虑过强制重新渲染 Log,但我知道这是不受欢迎的。有人看出我哪里出错了吗?

有问题的应用程序:https://calculatron-app.herokuapp.com/

最佳答案

this.setState() 是一个异步操作。因此,在调用 this.tenMostRecentLogs(this.state.logs) 时,它无法在调用 this.setState({}) 后立即获取更新的 logs 值。要立即获取更新的状态,您需要使用 this.setState 的回调函数。

例如: this.setState({logs:value,},()=>{ this.tenMostRecentLogs(this.state.logs) })

此外,this.tenMostRecentLogs() 不会返回任何值,就像您编写的return this.tenMostRecentLogs(this.state.logs) 一样。

请记住,函数返回任何原始或非原始数据类型值。它可能是函数、对象、数组或数字、字符串等...

关于javascript - 如何让我的列表组件在状态更改后呈现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56288219/

相关文章:

javascript - 我无法让 javaScript 执行我要求它执行的功能,在我的例子中,将两个值乘以隐藏值,然后添加最终值

javascript - 将 (this.state) 类型变量直接插入 JSX

javascript - 通过全局变量 react 互斥体

node.js - 未与 Cloud Functions 和 Firestore 建立连接

android - 为什么不是所有来自 FirebaseDatabase 引用的数据都添加到 ArrayList<String> 中?

javascript - 我怎样才能用javascript显示加载栏来显示正在运行的javascript的状态

javascript - post值无法进入controller

javascript - 如何编写进度条

node.js - Preact 到底是什么?我可以使用 Node 模块吗?

android - 如何按 firebase 中的子键值排序?