【问题标题】:Assignment of value in ComponentDidMount instead of constructor function in React在 ComponentDidMount 中赋值而不是 React 中的构造函数
【发布时间】:2019-04-20 04:58:55
【问题描述】:

以下是我的代码(运行良好),我可以在其中根据文本框中提供的输入对列表进行排序。在constructor 方法中,我这样声明了我的状态-

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

componentDidMount 方法中,我在tableData 中分配data 键状态。

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

我的问题是-这样做是否正确,因为我自己对此代码质量没有信心(将 tableData 初始化为[],然后在componentDidMount 方法中设置tableData: this.state.data)。让我知道我是否可以改进这一点,如果我 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>
    );
  }
}

【问题讨论】:

  • 如果将后者设置为第一个的值,为什么同时需要 data 和 tableData?为什么不从状态中删除数据并将 tableData 设置为初始值?关于 fetch,如果你只 fetch 一次,那么 componentDidMount 是一个很好的地方。
  • @Yossi 我尝试使用单一数据源进行此操作,但问题在于过滤 this.state.data 时也会发生变化,因此我还需要另一个变量来存储过滤后的数据跨度>
  • 我不明白。你能发布整个组件吗?
  • @Yossi 检查此代码 - codesandbox.io/s/k9j86ylo4o
  • 请贴在这里,对我来说更方便,如果需要也更容易参考代码段

标签: javascript reactjs fetch react-lifecycle


【解决方案1】:

你做得很好,但你是对的,有一种方法可以更好地做到这一点,处理两个事实点很难维护,所以你应该只有一个包含你需要的单词的数据数组,所以您应该过滤值的方法是通过在状态中创建一个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 错误,如果由于某种原因 word 不是字符串。

【讨论】:

    猜你喜欢
    • 2013-06-18
    • 1970-01-01
    • 2011-04-17
    • 2021-07-27
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    相关资源
    最近更新 更多