开发者问题收集

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

2019-02-18
3621

我是 React 的新手。我正在渲染组件 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" />;
  }
}

>

我想显示一个加载符号,直到渲染所有子元素。当前代码无法正常工作。有什么方法可以执行此操作吗?

2个回答
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>
        );
    }
    }
Nocebo
2019-02-18

我建议您在父组件 state 中为子组件添加 标志 ,例如 child1Loaded、child2Loaded 等 ,在 父组件 中有一个处理程序,以便从其 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 ,然后显示您的加载器。

Praveen Rao Chavan.G
2019-02-18