Как я могу получить компонент списка для отображения после изменения состояния? - PullRequest
0 голосов
/ 24 мая 2019

У меня есть приложение калькулятора, которое записывает десять самых последних уравнений, обработанных любым пользователем в режиме реального времени с помощью firebase.Предполагается, что журнал будет автоматически обновляться каждый раз, когда кто-либо с любого устройства по существу достигает знака равенства.Он делает это по большей части, за исключением того, что пользователь фактически нажимает «равно», и в этом случае он задерживается одним уравнением.Однако этот пользователь может видеть представления других в режиме реального времени.

У меня есть две разные переменные в состоянии.Один называется logs, который представляет собой объект, который сохраняет все журналы из базы данных локально, а другой называется list, который представляет собой массив, обновленный с помощью функции, которая обрабатывает журналы и получает десять самых последних записей в порядке времени.У меня есть компонент, который отображает список из десяти, чтобы создать li элементы в моем компоненте журнала.

Вот мой метод state и 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>

Я думал о принудительном повторном рендеринге Журнала, но я знаю, что это не одобряется.Кто-нибудь видит, где я иду не так?

Приложение под вопросом: https://calculatron -app.herokuapp.com /

Ответы [ 3 ]

2 голосов
/ 24 мая 2019

this.setState() - асинхронная операция.Поэтому при вызове this.tenMostRecentLogs(this.state.logs) он не может получить обновленное значение logs сразу после вызова this.setState({}).Чтобы немедленно получить обновленное состояние, вам нужно использовать функцию обратного вызова this.setState.

Например: this.setState({logs:value,},()=>{ this.tenMostRecentLogs(this.state.logs) })

Также this.tenMostRecentLogs() не возвращает никакого значения, как вы написалиreturn this.tenMostRecentLogs(this.state.logs).

Помните, что для функции нужно вернуть все, что является примитивным или не примитивным значением типа данных.Это могут быть функции, объекты, массивы или числа, строки и т. Д ...

1 голос
/ 24 мая 2019

Я помещаю это здесь как более чистый способ делать то, что вы хотите сделать.

fetchData = () => {
  const rootRef = firebase.database().ref().child('/logs');

  rootRef.on('value',
    snapshot => this.tenMostRecentLogs(snapshot.val()),
    errorObject => console.log("The read failed: " + errorObject.code)
  );
}

tenMostRecentLogs = obj => {
  // the rest of your operation...

  this.setState({
    list: tenLogsSorted,
    logs: obj
  });
}
0 голосов
/ 24 мая 2019
return this.tenMostRecentLogs(snapshot.val())

внутри fetchData () вместо

return this.tenMostRecentLogs(this.state.logs)

спасибо @LadiAden !!!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...