Реагировать, 2 установки в той же функции: второй стереть первый - PullRequest
0 голосов
/ 01 июня 2018

Я пытаюсь запустить приведенный выше код, но состояние обновляется только для idx.Из того, что я понимаю, setState второй функции не получит обновленное состояние, и именно поэтому это происходит.Есть ли способ заставить его работать должным образом (ожидайте, чем объединить 2 функции в одну)

doIt(idx,array) {
   this.doFirst(array);
   this.doSecond(idx);
}

doFirst(array){
   //bla bla bla code
   this.setState(test: {...this.state.test, array});
}

doSecond(idx) {
    // bla bla bla code
    this.setState(test: {...this.state.test, idx});
}

Ответы [ 5 ]

0 голосов
/ 01 июня 2018

Как уже отмечали другие, setState является асинхронным.Если вам нужно использовать предыдущее состояние, я хотел бы указать, что первый аргумент setState равен updater, для получения следующего состояния из предыдущего состояния может потребоваться функция:

doFirst(array){
   this.setState(previousState => ({ test: {...previousState.test, array} }));
}

doSecond(idx) {
    this.setState(previousState => ({ test: {...previousState.test, idx} }));
}
0 голосов
/ 01 июня 2018

Я предполагаю, что вы просто поставили скобки вокруг объекта состояния, поэтому я добавил их.

В любом случае, вы хотите использовать вместо этого функцию обновления:

this.setState((prevState, props) => ({test: {...prevState.test, array}});

Обратите внимание, что это, вероятно, не то, что вам нужно, поскольку в ES 2015 это означает: this.setState((prevState, props) => ({test: {...prevState.test, array: array}});

Вы хотели бы сделать то же самое и для другой функции.Пакеты реагирования устанавливают вызовы состояния вместе, поэтому, если вы не используете средство обновления, есть вероятность, что вы будете получать доступ к устаревшему состоянию для ваших последующих вызовов функций.Это, вероятно, то, что происходит в этом случае.

0 голосов
/ 01 июня 2018

Ниже два оператора выполняются одновременно.

this.doFirst(array);
this.doSecond(idx);

Оба звонят setState. setState is asynchronous.Таким образом, нет никакой гарантии, что значение будет обновляться последовательно.Из-за этого вызова гонки значение перезаписывается.лучше связать эти вызовы.

doIt(idx,array) {
   this.doFirst(array);   
}

doFirst(array){
   //bla bla bla code
   this.setState({test: {...this.state.test, array}},()=>{

    this.doSecond(idx); 
   });
}

doSecond(idx) { 
    this.setState({test: {...this.state.test, idx}});
}
0 голосов
/ 01 июня 2018

setState () является асинхронным.

Думайте о setState () как о запросе, а не как о немедленной команде для обновления компонента.Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход.React не гарантирует, что изменения состояния будут применены немедленно.

требуется дополнительная функция обратного вызова, которая будет выполнена после завершения setState и повторной визуализации компонента.Вы можете использовать этот обратный вызов.

Если следующее состояние зависит от предыдущего состояния, рекомендуется использовать форму функции обновления setState (updater [, callback])

doIt(idx,array) {
   this.doFirst(array, () => this.doSecond(idx));
}

doFirst(array, callback){
   //bla bla bla code
   this.setState(firstUpdaterFunction, callback);
}

doSecond(idx) {
    // bla bla bla code
    this.setState(2ndUpdaterFunction);
}

Ссылки:

https://reactjs.org/docs/react-component.html#setstate

https://stackoverflow.com/a/41446620/2073920

0 голосов
/ 01 июня 2018

Трудно сказать точно, потому что ваши примеры вызовов setState не совсем верны, this.setState(test: {...this.state.test, idx});.Вы имеете в виду, что вы делаете this.setState({test: {...this.state.test, idx}});?Если это так, вы должны использовать обратный вызов вместо объекта, подобного этому:

this.setState(() => ({ test: {...this.state.test, idx}})

...