Before I load my React App I need to check 2 conditions
So, inside render method, I have below conditions:
if (!this.isUserLoggedIn()) return <NotifyPleaseLogin />;
else if (!this.state.PageCheck) {
return (
<PageLoading
clientId={Config.clientId}
setPageReady={this.setPageReady()}
/>
);
} else {
return "Display the page";
In this scenario, what I expect to see happen is that, if user is not logged in, user redirected to login page. If user logged in and currently page is fetching the API query, user will see the PageLoading component (loading screen) and lastly if page is ready, the page will get displayed.
Right now I am getting Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.
Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.
error, which is because I am doing a setState update within Render method of the parent and also I am getting TypeError: props.setPageReady is not a function at PageLoading.js:29
error when I try to run parent's function that sets the state of PageReady to true like below
setPageReady() {
this.setState({ PageCheck: true });
}
How can I set this up so child can display a loading page until the page is ready (During this child can do an API call and retrieve user settings) then let parent know all settings are retrieved and are in the redux so parent can proceed loading the page?
You can easily achieve this by adding more states to actively control your component:
state = {
isAuthorized: false,
pagecheck: false
};
We move the authorization check to a lifecylcle-method so it doesn't get called every render.
componentDidMount() {
if(this.isUserLoggedIn()) {
this.setState({
isAuthorized: true
});
}
}
Using our state, we decide what to render.
render() {
const {
pagecheck,
isAuthorized
} = this.state;
if(!isAuthorized){
return <NotifyPleaseLogin />;
}
if(!pagecheck) {
return (
<PageLoading
clientId={Config.clientId}
setPageReady={() => this.setPageReady()}
/>
);
}
return "Display the page";
}
Note: Previously you passed this.setPageReady()
to Pageloading. This however executes the function and passes the result to Pageloading. If you want to pass the function you either need to remove the braces this.setPageReady
or wrap it into another function () => this.setPageReady()
You can pass PageCheck as prop from Parent to and show/hide loader in component based on that prop.
<PageLoading
clientId={Config.clientId}
pageCheck={this.state.PageCheck}
setPageReady={this.setPageReady}
/>
Then call setPageReady inside the success and error of the API call that you make in the child function:
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
})
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")
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.