Reputation: 11819
I need to check whether some props (from redux store) is an empty object or not. If it is empty, I want the page to redirect to another page and not bother to call render()
.
The current flow is something like:
constructor(props) {
this.checkObject();
}
checkObject() {
if (Object.keys(someObj).length === 0 && someObj.constructor === Object) {
this.props.history.push("/some-other-route");
}
}
render() {
// some code
}
However, when I do a console.log
, render()
is being called after checkObject()
which causes some errors because render()
needs a non-empty object to display content properly. That's the reason I don't want react to even call render()
if the object is empty (which I check through checkObject()
) and just redirect to another page.
So is there a lifecycle method to use that will execute my redirection code before render()
is called?
Upvotes: 3
Views: 2422
Reputation: 222979
history.push()
is a side effect that won't prevent the component to be initially rendered, so it belongs to componentDidMount
.
Since the result depends on props, the check could go to getDerivedStateFromProps
to provide redirect
flag in a component with local state. In a component that is connected to Redux it can be performed in mapStateToProps
:
connect(({ someObj }) => ({ redirect: !Object.keys(someObj) }))(...)
The component shouldn't be rendered if it will redirect:
componentDidMount() {
if (this.props.redirect)
this.props.history.push("/some-other-route");
}
render() {
return !this.props.redirect && (
...
);
}
As another answer correctly mentions, <Redirect>
component is a declarative alternative to calling history.push()
directly.
Upvotes: 0
Reputation: 485
Update:
Add super(props)
to your constructor. I think it should solve the problem. In this case, no need to componentWillMount()
. Your code should work just fine.
Unsafe and temporary solution:
You can use componentWillMount()
.
The first true life cycle method called is componentWillMount(). This method is only called one time, which is before the initial render.
constructor(props) {
}
checkObject() {
if (Object.keys(someObj).length === 0 && someObj.constructor === Object) {
this.props.history.push("/some-other-route");
}
}
componentWillMount() {
this.checkObject();
}
render() {
// some code
}
Upvotes: 0
Reputation: 1475
You could use the Redirect component of react-router within render.
import { Redirect } from 'react-router'
render(){
(checkIfObjectEmpty)?<Redirect to = '/some_route'/>:<JSX>
}
Upvotes: 2
Reputation: 6403
Return inside render
constructor(props) {
this.checkObject();
}
checkObject() {
return Object.keys(someObj).length === 0 && someObj.constructor === Object
}
render() {
if(this.checkObject()) return <Redirect to=/some-other-route" />
//rest of code not run if object is empty
}
Upvotes: 0