Ошибка при обновлении состояния React.js с <textarea> - PullRequest
0 голосов
/ 31 октября 2018

У меня есть форма с предварительно загруженной информацией для редактирования существующих объектов. Когда я редактирую информацию в поле ввода, все идет хорошо, но когда я пытаюсь редактировать контент в текстовой области, текст становится недоступным для набора текста. Если я изменю атрибут 'value' на 'defaultValue', старый текст не будет отображаться в текстовой области. Код моего компонента:

class PostEdit extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      id: this.props.match.params.id,
      post: []
    };
  }

  componentDidMount() {
    this.showPost(this.state.id);
  }

  showPost(id){
    fetch(`/api/v1/posts/${id}`, 
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
    }
    }).then((response) => {return response.json()})
    .then((data) => {this.setState({ post: data }) });
  }

  onChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  }

  render () {
    const { name, content } = this.state.post;
    return (
      <div>
        <form className="form" onSubmit={this.onSubmit}>
          <input id="name" className="form-control" type="text" name="name" defaultValue={name} onChange={this.onChange} required />
          <textarea id="content"  className="form-control" name="content" rows="8" cols="40" defaultValue={content} onChange={this.onChange}></textarea>    
          <input type="submit" value="Save" className="btn btn-success" id="btn-submit" />
        </form>
      </div>
    );
  }
}

Что я делаю не так и как я могу заставить текстовую область работать должным образом?

1 Ответ

0 голосов
/ 31 октября 2018

Если вы хотите, чтобы name и content были свойствами в this.state.post, тогда обновите начальный this.state в вашем constructor при минимальном изменении типа с массива [] на объект {} и обновите ваш обработчик onChange() до цели this.state.post. Также вам нужно будет использовать атрибут value на входе и текстовую область вместо defaultValue:

class PostEdit extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      id: this.props.match.params.id,
      post: {},
    };
  }

  componentDidMount() {
    this.showPost(this.state.id); // may consider using this.props.match.params.id instead here
  }

  showPost(id){
    fetch(`/api/v1/posts/${id}`, 
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
    }
    }).then((response) => {return response.json()})
    .then((data) => {this.setState({ post: data }) });
  }

  onChange = (e) => {
    this.setState({ post: { ...this.state.post, [e.target.name]: e.target.value } });
  }

  render () {
    const { name, content } = this.state.post;
    return (
      <div>
        <form className="form" onSubmit={this.onSubmit}>
          <input id="name" className="form-control" type="text" name="name" value={name} onChange={this.onChange} required />
          <textarea id="content"  className="form-control" name="content" rows="8" cols="40" value={content} onChange={this.onChange}></textarea>    
          <input type="submit" value="Save" className="btn btn-success" id="btn-submit" />
        </form>
      </div>
    );
  }
}

Вот пример в действии.

Надеюсь, это поможет!

...