反应预渲染条件

时间:2019-06-21 20:22:26

标签: javascript reactjs react-redux

在加载我的React App之前,我需要检查2个条件

  1. 用户已登录,如果未重定向到登录页面
  2. 所有 如果未显示加载屏幕,则使用API​​获取的用户设置。

因此,在render方法中,我具有以下条件:

if (!this.isUserLoggedIn()) return <NotifyPleaseLogin />;
else if (!this.state.PageCheck) {
  return (
    <PageLoading
      clientId={Config.clientId}
      setPageReady={this.setPageReady()}
    />
  );
} else {
  return "Display the page";

在这种情况下,我希望看到的是,如果用户未登录,则用户将重定向到登录页面。如果用户登录并且当前页面正在获取API查询,则用户将看到PageLoading组件(加载屏幕),最后,如果页面已准备就绪,则将显示该页面。

现在我收到Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.错误,这是因为我正在父级的Render方法中进行setState更新,并且当我尝试运行设置父级的函数时也遇到了TypeError: props.setPageReady is not a function at PageLoading.js:29错误如下所示,PageReady的状态变为true

setPageReady() {
    this.setState({ PageCheck: true });
  }

我该如何进行设置,以便子代可以显示加载页面,直到页面准备就绪(在此子代可以执行API调用并检索用户设置的过程中),然后让父代知道所有设置均已检索并位于redux中,因此父代可以继续加载页面吗?

3 个答案:

答案 0 :(得分:1)

您可以通过添加更多状态来主动控制组件来轻松实现这一目标:

state = {
    isAuthorized: false,
    pagecheck: false    
};

我们将授权检查移至生命周期方法,这样就不会在每个渲染器中都调用它。

componentDidMount() {
    if(this.isUserLoggedIn()) {
        this.setState({ 
            isAuthorized: true                
        });
    }   
}

使用状态,我们决定要渲染什么。

render() {
    const {
      pagecheck,
      isAuthorized
    } = this.state;

    if(!isAuthorized){
      return <NotifyPleaseLogin />;
    }

    if(!pagecheck) {
      return (
        <PageLoading
          clientId={Config.clientId}
          setPageReady={() => this.setPageReady()}
        />
      );    
    }

    return "Display the page";
}

注意:以前,您将this.setPageReady()传递给了Pageloading。但是,这将执行该功能并将结果传递给Pageloading。如果要传递函数,则需要删除括号this.setPageReady或将其包装到另一个函数() => this.setPageReady()

答案 1 :(得分:1)

您可以将PageCheck作为道具从父级传递到,并基于该道具在组件中显示/隐藏加载器。

  <PageLoading
      clientId={Config.clientId}
      pageCheck={this.state.PageCheck}
     setPageReady={this.setPageReady}
    />

然后在子函数中进行的API调用的成功和错误内部调用setPageReady:

axios.get(api)
.then((response) => {
     //assign or do required stuff for success
   this.props.setPageReady();
})
.catch((error) => {
    //do error related stuff
this.props.setPageReady();  //as you need to hide loader for error condition as well
})

答案 2 :(得分:1)

state = {
    isAuthorized: false,
    pageCheck: false    
};

componentDidMount() {
    if(this.isUserLoggedIn()) {
        this.setState({ 
            isAuthorized: true                
        });
    }   
}

{!this.state.isAuthorized ?
  <NotifyPleaseLogin />
:
(!this.state.pageCheck ?
  <PageLoading
      clientId={Config.clientId}
      setPageReady={this.setPageReady()}
   />
  :
  "Display the page")  
}