组件呈现乱序

Components rendering out of order

我正在使用 React 和 _underscorejs 从 JSON 对象数组中过滤单个数据元素,并将其呈现在 table 中的屏幕上。我的代码将呈现过滤后的数据,但随后整个 table 也会在几秒钟后呈现。

  this.state = { stats:[],
  value:'';

  componentDidMount() {
   fetch('http://localhost:5000/cityStats')
  .then((data) => data.json())
  .then((data) => this.setState( { stats: data } ))
  ;
  }
  // Using a select menu to select value
  handleChange = (e) => {
  this.setState({ value: e.target.value });

  // Filtering a element that matches  value choosen
  this.setState( { "stats": _.where(this.state.stats, 
  {NAME:e.target.value})});
   this.getDataAgain();
  }
  // 
  getDataAgain (){
  fetch('http://localhost:5000/citystats')
  .then((data) => data.json())
  .then((data) => this.setState( { stats: data } ));
  }

如果我不调用 getDataAgain(),则过滤器将只工作一次并显示一个空白列表。当用户选择一个选项时,如何修复它以仅显示过滤后的数据?

使用两个数组并调用一次端点,将原始数组保存在两个数组中this.setState({ stats: data, filtered: data})。使用 filtered 数组作为数据源。

state = { stats: [], filtered: [], value: '' };

componentDidMount = () => {
  this.getDataAgain();
}
// Using a select menu to select value
handleChange = e => {
  this.setState({ value: e.target.value });

  // Filtering a element that matches  value choosen
  const filtered = _.where(this.state.stats, { NAME: e.target.value });
  this.setState({
    filtered: filtered
  });
};
//
getDataAgain = () => {
  fetch('http://localhost:5000/citystats')
    .then(data => data.json())
    .then(data => this.setState({ stats: data, filtered: data }));
}

您当前使用的地方 stats,将其更改为 this.state.filtered

这里的主要问题是您正在用过滤后的对象覆盖数据。这绝对是一个错误的问题处理方法。在状态中设置数据后,不应更改它以避免额外的不必要的 api 请求。

注意:另外,您应该删除 getDataAgain 或将其命名为 getData 并仅在 CDM 方法中调用它以避免代码重复。

componentDidMount() {
   this.getData();
}

getData() {
  fetch('http://localhost:5000/cityStats')
  .then((data) => data.json())
  .then((stats) => this.setState( { stats } ))  
}

方法 1:使用私有 属性 到 set/unset 数据

  stats = undefined; // Will permanently hold the whole dataset

  componentDidMount() {
    fetch('http://localhost:5000/cityStats')
      .then(data => data.json())
      .then(stats => {
        this.stats = stats; // Saves the whole unfiltered dataset to private prop
        this.setState({ stats });
      });
  }

  handleChange = e => {
    const { value } = e.target.value;

    // In case value is unset it will revert stats to the whole unfiltered set 
    // from the data prop
    this.setState({
      value,
      stats: value ? _.where(this.state.stats, { NAME: value }) : this.stats
    });
  };

方法 2:在渲染中过滤(可选记忆)

只需在渲染中对其进行过滤即可。如果您没有庞大的数据集,这不会导致任何性能问题。

  render() {
    const { stats, value } = this.state;
    const filteredData = value
      ? _.where(stats, { NAME: value })
      : stats;

    .. do something with filteredData
  }

即使在数据集很大的情况下,您也应该在渲染函数中进行过滤,以便始终显示正确过滤的数据。唯一的区别是,在这种情况下,您将使用某种形式的记忆功能,以便为下一次渲染缓存每个过滤集。

基本示例:https://medium.com/@planttheidea/memoize-react-components-33377d7ebb6c