Показать новый элемент списка по клику с ReactJS - PullRequest
0 голосов
/ 19 декабря 2018

У меня проблема с обновлением и отображением массива в виде элементов списка одним нажатием кнопки.Из приведенного ниже кода я получаю сообщение об ошибке:

list.map не является функцией

import React from "react";


export default class InputPushToList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      ActiveText: "",
      li: ["First Item"]
    };

    this.handleOnClick = this.handleOnClick.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({
      ActiveText: e.target.value
    });
  }

  handleOnClick(e) {
    e.preventDefault();

    const newListItem = [this.state.ActiveText];

    this.setState({
      li: this.state.li.push(newListItem)
    });
  }

  render() {
    const list = this.state.li;
    return (
      <React.Fragment>
        <h2>{this.props.inputTitle}</h2>
        <input type="text" onChange={this.handleChange} />
        <h2>{this.state.ActiveText}</h2>
        <br />
        <button onClick={this.handleOnClick}>Add to list</button>

        <ul>
          {list.map(e => (
            <li>{e}</li>
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

На мой взгляд list.map является функцией, но, по-видимому, нет,так почему?И как бы вы начали отображать еще один элемент списка (это активное состояние элемента ввода this.state.ActiveText) при нажатии кнопки?Спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

Проблема в этой строке:

this.setState({
      li: this.state.li.push(newListItem)
    });

пример:

var arr = [];
console.log(arr.push({}))// it will print 1.

в вашем случае:

this.setState({
      li: this.state.li.push(newListItem)// here you assigned `li`1.
    });

Исправьте вышесказанное.

0 голосов
/ 19 декабря 2018

1.Не изменяйте this.state

В handleOnClick(), не пишите this.state.li.push(newListItem).

Вместо этого создайте клон this.state.li, добавьте newListItem в этот клон иустановите состояние li для нового клона:

handleOnClick(e) {
  e.preventDefault();
  this.setState({
    li: [
      ...this.state.li, // spread out the existing li
      this.state.ActiveText // append this newListItem at the end of this array
    ]
  });
}

2.Рассмотрим деструктурирование

В вашем render() вы можете деструктировать this.state.li:

render() {
  const { li } = this.state
  return (
    <React.Fragment>
      ...other stuffs
      <ul>
        {li.map(e => (
          <li>{e}</li>
        ))}
      </ul>
    </React.Fragment>
  );
}
0 голосов
/ 19 декабря 2018

Прежде всего, вы не используете this.state внутри this.setState, вместо этого используйте функцию для обновления состояния.Проверьте это для справки: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Ваш код должен выглядеть следующим образом:

this.setState((state) => ({
  li: state.li.concat([newListItem])
}));

Во-вторых, почему вы присваиваете массив newlistitem, выполняя: const newListItem = [this.state.ActiveText];?

Это должно быть const newListItem = this.state.ActiveText;

...