延迟父组件渲染,直到所有子组件渲染 reactjs

Delay parent component render till all the child components render reactjs

我是反应初学者。我正在渲染组件 A。该组件中还有 5 个子组件。他们每个人都在请求 API 并从 api 加载信息。我想显示一个加载符号,直到收到并呈现所有响应。我真的不确定如何实际执行此操作。例如:

class Home extends React.Component {
constructor() {
  super();
  this.state = {
    isLoggedIn: getCookie("Authorization") ? true : false,
    loading: true
  };
}

componentDidMount() {
  this.setState({ loading: false });
}

render() {
  document.body.style = "background: #fafafa;";
  if (this.state.isLoggedIn) {
    return (
      <div>
        {this.state.loading ? <Loading /> : ""}
        <Child1 />
        <Child2 />
        <Child3 />
        Welcome Home, user
      </div>
    );
  } else {
    // User not logged, error
    return <Redirect to="/login" />;
  }
}

}

我想显示一个加载符号,直到所有子元素都被渲染。目前的代码不能正常工作。有什么办法可以做到这一点吗?

我建议您在父组件 state 中为您的子组件设置 flags,例如 child1Loaded,child2Loaded,。 ..etc,在 父组件 中有一个处理程序从他们的 componentDidMount().

更新这个
     this.state = {
        isLoggedIn: getCookie("Authorization") ? true : false,
        loading: true,
        child1Loaded:false,
        child2Loaded:false,
        child3Loaded:false,
        child4Loaded:false,
        child5Loaded:false,
      };

      updateLoadedFlagHandler = (childName) =>{
        this.setState({[childName]:true});
      }

      render() {
        document.body.style = "background: #fafafa;";
       if (this.state.isLoggedIn) {
       return (
       <div>
        {this.state.loading ? <Loading /> : ""}
        <Child1 loadedUpdateHandler={updateLoadedFlagHandler} childName='child1Loaded'/>
        <Child2 loadedUpdateHandler={updateLoadedFlagHandler} childName='child2Loaded'/>
        <Child3 loadedUpdateHandler={updateLoadedFlagHandler} childName='child3Loaded'/>
        Welcome Home, user
       </div>
    );
  } else {
    // User not logged, error
    return <Redirect to="/login" />;
  }
}

子组件:

 componentDidMount(){
   this.props.loadedUpdateHandler(this.props.childName);
 }

您可以检查所有这些标志是否为 true,然后显示您的加载器。

class Home extends React.Component {
constructor() {
  super();
  this.state = {
    isLoggedIn: getCookie("Authorization") ? true : false,
    loading: true,
    childrenLength: 3
    childrenLoaded: 0
  };
}

componentDidMount() {
  this.setState({ loading: false });
}

onChildLoad = () => { //Using arrow functions instead of binding
  this.setState({childrenLoaded: this.state.childrenLoaded + 1}, () => {
   if(this.state.childrenLoaded === this.state.childrenLength){
     this.setState({loading: false});
   }
 })
}

render() {
  document.body.style = "background: #fafafa;";
  if (this.state.isLoggedIn) {
    return (
      <div>
        {this.state.loading && <Loading />}
              <div>
                <Child1 onChildLoad={this.onChildLoad} loading={this.state.loading}/>
                <Child2 onChildLoad={this.onChildLoad} loading={this.state.loading}/>
                <Child3 onChildLoad={this.onChildLoad} loading={this.state.loading}/>
                Welcome Home, user
              </div>
      </div>
    );
  } else {
    // User not logged, error
    return <Redirect to="/login" />;
  }
}
}

这可能不是最流畅的解决方案,但它可能有效

编辑

假设你必须在你的子组件中加载一些东西,你可以这样做:

class Child extends React.Component {
    constructor() {
      super();
      this.state = {
        isLoaded: false
      };
    }

    componentDidMount() {
      // Load something here...
      this.setState({isLoaded: true}, () => this.props.onChildLoad());
    }

    render() {
        return (
          <div>
            {
              // The content of the child will only be displayed if the component is loaded itself and the parent component is fully loaded as well
              (this.state.isLoaded && !this.props.loading) &&
                 <div>
                   Here is your child
                 </div>
             }
          </div>
        );
    }
    }