React setState не обновляется

#javascript #setstate

Вопрос:

 handleSkipThisQuestionClicked = () => {
    const { answersDict, currentIndex, currentQuestionGroupId } = this.state;
    if (currentIndex < answersDict[currentQuestionGroupId].length - 1) {
        this.setQuestionDetails(answersDict[currentQuestionGroupId][currentIndex   1]);
    } else {
        // set current index to 0 and increase the current group
        debugger;
        this.setState((prevState) => ({
            currentQuestionGroupId: prevState.currentQuestionGroupId   1,
            currentIndex: 0,
        }));
        this.setQuestionDetails(answersDict[this.state.currentQuestionGroupId][0]);
    }
};
 

В этом коде в else блоке при вызове функции setState состояние не изменяется

Примечание: Даже если это асинхронно, это не меняет всего через долгое время

Может ли эта проблема быть связана с разрушением состояния ES6

Редактировать

Я вошел в систему и проверил обратный вызов, и все равно состояние остается неизменным

 handleSkipThisQuestionClicked = () => {
        const { answersDict, currentIndex, currentQuestionGroupId } = this.state;
        if (currentIndex < answersDict[currentQuestionGroupId].length - 1) {
            this.setQuestionDetails(answersDict[currentQuestionGroupId][currentIndex   1]);
        } else {
            // set current index to 0 and increase the current group
            debugger;
            this.setState(
                (prevState) => ({
                    currentQuestionGroupId: prevState.currentQuestionGroupId   1,
                    currentIndex: 0,
                }),
                () => {
                    console.log(this.state.currentQuestionGroupId);
                    console.log(this.state.currentIndex);
                },
            );
            this.setQuestionDetails(answersDict[this.state.currentQuestionGroupId][0]);
        }
    };

 

Комментарии:

1. Есть ли setQuestionDetails также состояние set?

2. Не видя больше вашего компонента, мы можем только догадываться, что здесь происходит не так. Но я с подозрением отношусь к этому последнему вызову: this.setQuestionDetails(answersDict[this.state.currentQuestionGroupId][0]) , потому this.state.currentQuestionGroupId что в этот момент он все равно будет принимать «старое» значение. Я не знаю, что setQuestionDetails делает, но вы вполне можете непреднамеренно «сбросить» старую «группу вопросов» здесь.

3. Нет, он просто вызывает API

4. @RobinZigmond В setQuestionDetails Предположим, что я хочу позвонить setQuestionDetails с обновленными значениями, нет изменений состояния, даже обратный вызов зарегистрировал значения prevState

5. «как мне убедиться, что состояние обновлено» — вы имеете в виду, как вы можете убедиться, что состояние обновлено, прежде чем делать что-то дальше? Аргумент обратного вызова setState — это то, как вы это делаете, что вы показали во втором фрагменте-если это не работает, есть более глубокая проблема, но трудно понять, что именно, не видя воспроизводимого примера вашего кода. Не могли бы вы, возможно, сделать простой codesandbox, чтобы продемонстрировать свою проблему?

Ответ №1:

Вы всегда можете скопировать состояние в локальный var, внести изменения и снова установить состояние. Что-то вроде:

 handleSkipThisQuestionClicked = () => {
    const { answersDict, currentIndex, currentQuestionGroupId } = this.state;
    if (currentIndex < answersDict[currentQuestionGroupId].length - 1) {
        this.setQuestionDetails(answersDict[currentQuestionGroupId][currentIndex   1]);
    } else {
        // set current index to 0 and increase the current group
        debugger;
        let result = Object.assign({}, this.state);
        result.currentQuestionGroupId  ;
        result.currentIndex = 0;

        this.setState({ result });
        this.setQuestionDetails(answersDict[result.currentQuestionGroupId][0]);
    }
};
 

Комментарии:

1. @SanjayKapilesh рад это слышать. Приятного кодирования =)

Ответ №2:

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

 this.setState(prevState => ({
  currentQuestionGroupId: prevState.currentQuestionGroupId   1,
  currentIndex: 0,
}), () => this.setQuestionDetails(answersDict[this.state.currentQuestionGroupId][0]);