Реагировать с ES7: Uncaught TypeError: Невозможно прочитать состояние свойства undefined

Я получаю сообщение об ошибке Uncaught TypeError: не удается прочитать состояние свойства undefined всякий раз, когда я что-либо ввожу в поле ввода AuthorForm. Я использую React с ES7.

Ошибка возникает в 3-й строке функции setAuthorState в ManageAuthorPage. Независимо от этой строки кода, даже если я помещу console.log (this.state.author) в setAuthorState, он остановится на console.log и вызовет ошибку.

Не могу найти аналогичную проблему для кого-то еще в Интернете.

Вот код ManageAuthorPage:

import React, { Component } from 'react';
import AuthorForm from './authorForm';

class ManageAuthorPage extends Component {
  state = {
    author: { id: '', firstName: '', lastName: '' }
  };

  setAuthorState(event) {
    let field = event.target.name;
    let value = event.target.value;
    this.state.author[field] = value;
    return this.setState({author: this.state.author});
  };

  render() {
    return (
      <AuthorForm
        author={this.state.author}
        onChange={this.setAuthorState}
      />
    );
  }
}

export default ManageAuthorPage 

А вот код AuthorForm:

import React, { Component } from 'react';

class AuthorForm extends Component {
  render() {
    return (
      <form>
                <h1>Manage Author</h1>
        <label htmlFor="firstName">First Name</label>
                <input type="text"
                    name="firstName"
          className="form-control"
                    placeholder="First Name"
          ref="firstName"
          onChange={this.props.onChange}
                    value={this.props.author.firstName}
          />
        <br />

        <label htmlFor="lastName">Last Name</label>
                <input type="text"
                    name="lastName"
          className="form-control"
                    placeholder="Last Name"
          ref="lastName"
                    onChange={this.props.onChange}
          value={this.props.author.lastName}
                    />

                <input type="submit" value="Save" className="btn btn-default" />
            </form>
    );
  }
}

export default AuthorForm

person Khpalwalk    schedule 09.02.2016    source источник
comment
Вы НЕ ДОЛЖНЫ изменять состояние напрямую. Для этого есть asynchronous setState (...). Пишу об этом заявлении this.state.author[field] = value;.   -  person Leonid Dashko    schedule 13.09.2018


Ответы (2)


Убедитесь, что вы вызываете super() первым делом в конструкторе.

Вы должны установить this для setAuthorState метода

class ManageAuthorPage extends Component {

  state = {
    author: { id: '', firstName: '', lastName: '' }
  };

  constructor(props) {
    super(props);
    this.handleAuthorChange = this.handleAuthorChange.bind(this);
  } 

  handleAuthorChange(event) {
    let {name: fieldName, value} = event.target;

    this.setState({
      [fieldName]: value
    });
  };

  render() {
    return (
      <AuthorForm
        author={this.state.author}
        onChange={this.handleAuthorChange}
      />
    );
  }
}

Другая альтернатива, основанная на arrow function:

class ManageAuthorPage extends Component {

  state = {
    author: { id: '', firstName: '', lastName: '' }
  };

  handleAuthorChange = (event) => {
    const {name: fieldName, value} = event.target;

    this.setState({
      [fieldName]: value
    });
  };

  render() {
    return (
      <AuthorForm
        author={this.state.author}
        onChange={this.handleAuthorChange}
      />
    );
  }
}
person Oleksandr T.    schedule 09.02.2016
comment
у меня сработал альтернативный метод Спасибо за ответ - person Sumit Ghewade; 11.04.2020

Вы должны привязать обработчики событий к правильному контексту (this):

onChange={this.setAuthorState.bind(this)}
person madox2    schedule 09.02.2016
comment
Я использовал твой пример, приятель. Спасибо. - person Khpalwalk; 09.02.2016
comment
@Khpalwalk Добро пожаловать :-) - person madox2; 09.02.2016
comment
Я считаю, что более красноречивый способ сделать это - использовать стрелочные функции, которые по своей сути связывают это с функцией, я считаю это особенно полезным при написании кода реакции. Таким образом, вы можете использовать setAuthorState = event = ›{...}. Для привязки этого к функции не требуется дополнительных строк кода. Кроме того, каждый раз, когда этот компонент щелкают, не требуется дополнительных затрат на его привязку. - person Brett Reinhard; 05.08.2017
comment
@BrettReinhard, вы правы, на данный момент это, наверное, самый удобный способ. В любом случае, JS-программистам необходимо понимать причину привязки контекста. - person madox2; 05.08.2017
comment
Я согласен, мне кажется, что «это» ускользает от многих разработчиков, и они не до конца понимают, что на самом деле представляет собой «это». Мне кажется, что разработчики React лучше понимают «это», но теперь другое дело, является ли это чисто поверхностным. Тем, кто не понимает «это», стоит взглянуть на Kyle Simpsons, вы не знаете репозиторий js на github. Его имя пользователя - getify, и в нем есть несколько глав, посвященных «этому», которые помогут разобраться в том, что «это» означает в данном контексте. - person Brett Reinhard; 07.08.2017
comment
да, спасибо, это работает для меня. Я забыл использовать привязку в своем коде. - person Faris Rayhan; 12.03.2018
comment
да, спасибо, это работает для меня. Я забыл использовать привязку в своем коде. - person Faris Rayhan; 12.03.2018
comment
сделай это в своем конструкторе - person imran haider; 05.03.2021