Когда у меня есть класс кнопки "DrawButton", у которого есть этот рендер

render() {
    return(
        <Button
            onClick={this.props.toggleDraw.bind(this)}
            style={{
                backgroundColor: this.props.drawMode ? 'red' : 'blue'
            }}
        >
            Draw
        </Button>
    );
}

И в родительском App.js состояние определяется

state = {
        drawMode: false
}

И есть функция-обработчик

toggleDraw = (e) => {
    console.log('App.js drawMode:' + this.state.drawMode);
    this.setState({
        drawMode: !this.state.drawMode
    });
    console.log('App.js drawMode:' + this.state.drawMode);
}

И наконец кнопка:

render() {
  return (
    <div className="App">
        <DrawButton 
            toggleDraw={this.toggleDraw} 
            drawMode={this.state.drawMode}
        />
    </div>
  );
}

Состояние не обновляется должным образом. Он выводит следующее:

Сначала нажмите кнопку

App.js drawMode:false
App.js:27
App.js drawMode:false
App.js:31

Перед запуском setState drawMode имеет значение false, после запуска setState, drawMode все еще остается false.

Но кнопка по-прежнему имеет красный фон.

Второй щелчок по кнопке:

App.js drawMode:true
App.js:22
App.js drawMode:true
App.js:26

Но кнопка снова синего цвета despise drawMode в состоянии установлено значение true.

Почему происходит это несоответствие?

-2
user6329530 28 Окт 2019 в 04:33
2
setState является асинхронным, поэтому он не будет изменен в следующей строке кода при регистрации.
 – 
Jayce444
28 Окт 2019 в 04:36
1
У вас есть .bind(this) не в том месте, оно должно быть в родительском, а не в дочернем элементе.
 – 
david
28 Окт 2019 в 04:36
Как я могу исправить, чтобы он оставался последовательным?
 – 
user6329530
28 Окт 2019 в 04:36
1
Какая? здесь нет асинхронной функции.
 – 
david
28 Окт 2019 в 04:38
1
Тогда вы не показываете нам весь код. С вашим кодом и моим исправлением все работает нормально (за исключением журнала консоли, о котором говорят другие люди) jsfiddle.net/dh7mkzwq< /а>
 – 
david
28 Окт 2019 в 04:43

1 ответ

Лучший ответ

Во-первых, ваш bind использовался неправильно, в вашем DrawButton обработчике onClick просто вызовите this.props.toggleDraw. Этот код: this.props.toggleDraw.bind(this) должен быть в конструкторе файла App.js.

Во-вторых, не используйте console.log для проверки значения состояния после настройки, поскольку функция setState работает асинхронно, используйте обратный вызов setState для проверки значения после настройки:

toggleDraw = (e) => {
    console.log('App.js drawMode:' + this.state.drawMode);
    this.setState(
        { drawMode: !this.state.drawMode },
        () => console.log('App.js drawMode:' + this.state.drawMode)
    ),
}
1
thelonglqd 28 Окт 2019 в 04:48
Вы правы, это устраняет проблему с журналом консоли. Но теперь состояние не передается правильно всем компонентам. Я только что добавил еще один компонент, и хотя кнопка получает обновленное состояние drawMode, другой компонент, определенный ранее, не получает его одновременно. Я должен переключить его дважды, пока он не будет заполнен другим компонентом. Я отредактирую вопрос соответственно.
 – 
user6329530
28 Окт 2019 в 04:54
Не могли бы вы добавить код «другого» компонента, я посмотрю на это.
 – 
thelonglqd
28 Окт 2019 в 04:56
2
Может быть, мне следует создать еще один вопрос с этим, потому что это слишком сильно меняет вопрос...
 – 
user6329530
28 Окт 2019 в 05:00