避免在React中的每个渲染上重新计算变量

时间:2016-02-11 06:59:15

标签: javascript reactjs redux

我有一个组件ParentToDataDisplayingComponent正在创建一些查找,以帮助根据ParentToDataDisplayingComponent的父级访问的redux存储中的数据格式化子组件的数据。

我在组件重新渲染方面有些滞后,其中更改状态未影响this.props.dataOnethis.props.dataTwo - 这些查找中的数据保证与上次渲染相同,但道具中的数据在组件安装时,不保证可用(从后端加载)。只有在通过道具传递的所有数据都可用后才会调用mapPropsToDisplayFormat()

我想声明一次查找变量,并避免在每次重新渲染时重新keyBy()

有没有办法在ParentToDataDisplayingComponent组件中执行此操作?

export default class ParentToDataDisplayingComponent extends Component {

  ...     

  mapPropsToDisplayFormat() {
    const lookupOne = _(this.props.dataOne).keyBy('someAttr').value();
    const lookupTwo = _(this.props.dataTwo).keyBy('someAttr').value();

    toReturn = this.props.dataThree.map(data => 

      ... // use those lookups to build returnObject

    );

    return toReturn;
  }

  hasAllDataLoaded() {
    const allThere = ... // checks if all data in props is available
    return allThere //true or false
  }

  render() {
    return (
      <div>

        <DataDisplayingComponent
          data={this.hasAllDataLoaded() ? this.mapPropsToDisplayFormat() : "data loading"}
        />
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:3)

将所有数据加载的结果保存到组件的状态。

export default class ParentToDataDisplayingComponent extends Component {

  constructor(props) {
    super(props)
    this.state = { data: "data loading" }
  }    

  componentWillReceiveProps(nextProps) {
    // you can check if incoming props contains the data you need.
    if (!this.state.data.length && nextProps.dataLoaded) {
      this.setState({ data: mapPropsToDisplayFormat() })
    }
  }

  ...

  render() {
    return (
      <div>
        <DataDisplayingComponent
          data={this.state.data}
        />
      </div>
    );
  }
}

我认为根据您在道具中检查的确切内容以查看您的数据是否已完成加载,您可以使用shouldComponentUpdate来获得类似的结果而不保存本地状态。

export default class ParentToDataDisplayingComponent extends Component {

shouldComponentUpdate(nextProps) {
  return nextProps.hasData !== this.props.hasData
}    

mapPropsToDisplayFormat() {
  ...

  toReturn = data.props.dataThree
    ? "data loading"
    : this.props.dataThree.map(data => ... )

  return toReturn;
}  

  render() {
    return (
      <div>
        <DataDisplayingComponent
          data={this.mapPropsToDisplayFormat()}
        />
      </div>
    );
  }
}