Почему состояние реакции не изменяется одновременно с изменением ввода для контролируемого компонента

#reactjs

#reactjs

Вопрос:

Я не думаю, что я что-то пропустил, сделав форму контролируемым компонентом. Почему состояние не изменяется при вводе символов?

 class AddChores extends Component {
  state = {
    chore: "",
  };

  handleChange = (evt) => {
    this.setState({ chore: evt.target.value });
  };

  handleSubmit = (evt) => {
    evt.preventDefault();
    this.props.addChores(this.state);
    this.setState({ chore: "" });
  };

  render() {
    console.log(this.state);
    return (
      <div>
        <form onClick={this.handleSubmit}>
          <input
            type="text"
            placeholder="New Chore"
            value={this.state.chore}
            onChange={this.handleChange}
          />
          <button className="button">ADD CHORE</button>
        </form>
      </div>
    );
  }
}[![React dev tool showing no simultaneous update][1]][1]
  

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

1. должно ли событие передаваться здесь onChange={this.handleChange} ?

2. я думаю, вам нужно инициализировать состояние в конструкторе: constructor = () => {this.state={chore: «»}}

3. Вы проверили свою консоль на наличие каких-либо сообщений об ошибках?

4. Я попытался передать объект evt. Я попробовал полную форму конструктора constructor(props){super(props};this.state={chore:»}} . Я попробовал это.setState(() =>({chore:evt.target.value})). Я попробовал this.setState({chore:evt.target.value}, () => console.log(this.state)). Я попробовал несколько комбинаций из вышеперечисленных. Пока ничего не работает. Странно.

5. Ошибка на консоли отсутствует

Ответ №1:

Я внес некоторые изменения, как показано ниже, и у меня все работает нормально. Надеюсь, это вам тоже поможет.

  class AddChores extends Component {
  constructor(props) {
    super(props);
    this.state = {
      chore: ""
    };
   
  }

  handleChange = (event) => {
    this.setState({
      chore: event.target.value
    });
    
  };

  handleSubmit = (evt) => {
    evt.preventDefault();
    // this.props.addChores(this.state);
    this.setState({ chore: "" });
  };
  
  componentDidUpdate(){
    console.log('the state', this.state.chore)
  }

  render() {
    return (
      <div>
        <form onClick={this.handleSubmit}>
          <input
            type="text"
            placeholder="New Chore"
            value={this.state.chore}
            onChange={this.handleChange}
          />
        </form>
       </div>
    );
  }
}
  

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

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

2. Я заметил, что на консоли теперь отображается изменение состояния без привязки методов в конструкторе. Это инструмент разработки, который не показывает его. Не уверен, ошибка это или что. Спасибо Saba за предложение явно регистрировать его на консоли. Я больше сосредоточился на инструменте разработки.

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

4. Если вы попытаетесь зарегистрировать состояние в том же цикле рендеринга, что и обновление состояния в очереди, оно будет регистрировать текущее состояние, а не состояние, которое нужно обновить. Вы можете использовать либо setState обратный вызов, либо, что лучше, метод жизненного цикла, например componentDidUpdate , для регистрации обновленного состояния. Кроме того, кроме перемещения журнала и удаления внешнего вызова this.props. addChores , чем это отличается от кода OP?

Ответ №2:

не уверен, почему это происходит, но попробуйте использовать вторую форму setState
this.setState(() => ({ chore: evt.target.value})) проверки этого https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous