如何在不等待所有儿童登机的情况下提早提取?

时间:2019-04-02 09:41:35

标签: reactjs performance

我具有以下React组件结构:

<A>
  <B>
    <C/>
  </B>
</A>

我在组件A中获取数据。目前,我将提取逻辑放入componentDidMount中。但是基于 https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount

  

在父组件之前调用子组件的componentDidMount()方法。

因此,仅在挂载并渲染ABC后才进行抓取

由于在我们的案例中,A具有深层嵌套的组件,因此提取操作需要等待所有渲染和安装的组件。

有没有办法提早提取?

3 个答案:

答案 0 :(得分:1)

通过遵循上面评论部分中的@Julien Bourdic和@Jayavel建议,我们设法将性能提高了高达2秒。

      state = {
        isReady: false
      }

      componentDidMount() {
        fetch();
        this.setState({ isReady: true });
      }

      render() {
        return this.state.isReady ? <Wrapped {...this.props} /> : null;
      }

基本上,我们在提取未完成时渲染null。这样,组件BC不会被挂载和渲染,从而允许A的{​​{1}}(和componentDidMount)更早地启动。

答案 1 :(得分:1)

  

在父组件之前调用子组件的componentDidMount()方法。

在执行异步操作时,请显示加载微调框或其他内容,直到获取所有信息,如下所示:

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React',
      data: [],
      isLoading: true
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(response => response.json())
      .then(data =>
        this.setState(() => {
          return { data , isLoading: false};
        })
      );
  }

  render() {
    if (this.state.isLoading) {
      return <p>Loading ...</p>; // initially isLoading is true, it renders a loading after fetch components will render
    }
    return (
      <div>
      <ul>
        {this.state.data.map(data => {
          return <li key={data.username}>{data.username} </li>
        })}
      </ul>
        <Hello name={this.state.name}>
          <p>
            Start editing to see some magic happen :)
          </p>
        </Hello>

      </div>
    );
  }
}

Demo

答案 2 :(得分:0)

如果您想继续使用React的生命周期方法,一个不错的选择是在调用componentDidMount并且数据提取出来之前不要渲染该组件的子组件。您可以使用setState进行管理。

或者,您可以考虑在React生命周期之外获取数据。根据您使用哪种状态管理解决方案以及应用程序的总体架构,这可能是一个不错的选择。