ReactJS setState не работает с параметром / аргументом из метода / функции - PullRequest
2 голосов
/ 06 октября 2019

Я не могу заставить setState изменить (изменить) значение, полученное из аргумента или параметра метода / функции. По крайней мере, это не работает при первом вызове. Мне нужно вызвать setState дважды, прежде чем значение изменится.

import React from 'react'

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      testItem: 'originalValue'
    }
  }

  updateState(input) {
    this.setState({
      testItem: input
    },
      console.log(this.state.testItem) // displays 'originalValue' instead of 'newValue!', at least on the first call
    )
  }

  render() {
    return (
      <button onClick={() => this.updateState('newValue!')}>
        Change State
        </button>
    )
  }
}

export default App

Состояние 'testItem' должно измениться с 'originalValue' на 'newValue!'(берется из аргумента 'input' в методе 'updateState (input)') при нажатии кнопки, но не изменяется при первом щелчке (даже при использовании обратного вызова в setState). Он меняется только когда я нажимаю на кнопку второй раз. Почему это?

Ответы [ 3 ]

2 голосов
/ 06 октября 2019

Прямо сейчас, console.log сразу вызывается с текущим состоянием, которое является начальным состоянием, которое вы установили, потому что setState является асинхронным (то есть состояние не обновляется немедленно с последним изменением).

Из-за этого нам нужно отложить вызов console.log, заключив его в функцию. Мы делаем это так, чтобы он мог позже вызываться setState, а не каждый раз, когда вы вызываете setState

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

this.setState({ testItem: input}, () => console.log(this.state))
0 голосов
/ 06 октября 2019

Это происходит потому, что setState является асинхронным. Вы можете использовать обратный вызов или асинхронное ожидание. Решение обратного вызова уже дано. Я хотел бы дать решение с async-await -

async updateState(input) {
    await this.setState({
      testItem: input
    });
    console.log(this.state.testItem);
}
0 голосов
/ 06 октября 2019

Это произошло потому, что перед обновлением состояния был запущен console.log(this.state.testItem). Поскольку setState носит асинхронный характер. Чтобы этого избежать:

  1. Решение для взлома - используйте setTimeout (дождитесь его обновления)
   updateState(input) {
    this.setState({
      testItem: input
    });
    setTimeOut (() => {
      console.log(this.state.testItem)
    }) 
  }
Предпочтительный способ - передать обратный вызов в качестве второго параметра
   updateState(input) {
    this.setState({
      testItem: input
    }, () => console.log(this.state.testItem))
   }
...