Присвоение значения в ComponentDidMount вместо функции конструктора в React - PullRequest
0 голосов
/ 20 апреля 2019

Ниже приведен мой код (который работает нормально), в котором я могу сортировать список на основе ввода, предоставленного в текстовом поле.В методе constructor я объявил свои состояния следующим образом -

this.state = {
      data: ["Adventure", "Romance", "Comedy", "Drama"],
      tableData: []
    };

В методе componentDidMount я назначил состояние ключа data в tableData.

  componentDidMount() {
    this.setState({
      tableData: this.state.data
    });
  }

Мой вопросis - это правильный способ сделать это, так как я сам не уверен в качестве этого кода (инициализирую tableData как [], а затем устанавливаю tableData: this.state.data в методе componentDidMount).Дайте мне знать, если я могу улучшить это также, что изменится, если я fetch данные из API, который является лучшим местом для инициализации и использования в приложении.

Пример рабочего кода - https://codesandbox.io/s/k9j86ylo4o

Код -

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: ["Adventure", "Romance", "Comedy", "Drama"]
    };
    this.handleChange = this.handleChange.bind(this);
  }

  refineDataList(inputValue) {
    const listData = this.state.data;
    const result = listData.filter(item =>
      item.toLowerCase().match(inputValue.toLowerCase())
    );
    this.setState({
      data: result
    });
  }

  handleChange(e) {
    const inputValue = e && e.target && e.target.value;
    this.refineDataList(inputValue);
  }
  render() {
    return (
      <div className="App">
        <h3>DATA SEARCH</h3>
        <div className="form">
          <input type="text" onChange={this.handleChange} />
        </div>
        <div className="result">
          <ul>
            {this.state.data &&
              this.state.data.map((item, i) => {
                return <li key={i}>{item}</li>;
              })}
          </ul>
        </div>
      </div>
    );
  }
}

1 Ответ

1 голос
/ 20 апреля 2019

У вас все отлично, но вы правы, есть способ сделать это лучше, справиться с двумя пунктами истины сложно, поэтому у вас должен быть только один массив данных со словами, которые вам нужны, поэтомуВы должны фильтровать значения, создав переменную filter в состояние для хранения текущего слова, которое нужно отфильтровать, поэтому вы должны добавить что-то вроде

// in the constructor function
constructor(props) {
  super(props);
  this.state = {
    data: ["Adventure", "Romance", "Comedy", "Drama"],
    filter: ""
  }
}

// create a filter function
getFilteredResults() {
  const { filter, data } = this.state;
  return data.filter(word => String(word).toLowerCase().match(filter));
}

// and finally into your render function
render() {
  return (
    <div>
      {this.getFilteredResults().map((word) => (
        <div>{word}</div>
      ))}
    </div>
  );
}

Очевидно, не забудьте обновить функцию handleChange,вот так

handleChange(e) {
  const inputValue = e && e.target && e.target.value;
  this.setState({ filter: inputValue });
  //this.refineDataList(inputValue);
}

Таким образом, вы будете поддерживать только одну точку истины, она будет работать как положено.

Примечание: мы используем String(word).toLowerCase(), чтобы гарантировать, что текущий wordна самом деле string, поэтому мы можем избежать ошибки toLowerCase is not function of undefined, если по какой-то причине слово не является строкой.

...