Reputation: 174
Im populating my state with an async call inside componentDidMount. If the fetch fails, I want to redirect the user. The redirect is done with a <PageNotFound />
component. See below:
class Product extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
getProduct(this.props.productId).then(product =>
this.setState({ product })
);
}
render() {
return this.state.product ? (
<ProductView product={product}/>
) : (
<PageNotFound />
);
}
}
The issue is that React is running the render()
method before the async call finishes. This results in redirecting the user before the async call finishes. The only fix I can see is adding an additional isLoading
flag on the state, but Im wondering if there is another workaround for this.
Upvotes: 1
Views: 559
Reputation: 174
Answer suggested by Easwar
class Product extends React.Component {
constructor(props) {
super(props);
this.state = { fetchingProduct: true }
}
componentDidMount() {
getProduct(this.props.productId)
.then(product => this.setState({ product, fetchingProduct: false }))
.catch(() => this.setState({ fetchingProduct: false }))
}
render() {
return fetchingProduct ? (
this.state.product ? (
<ProductView product={product}/>
) : (
<PageNotFound />
)
) : (
<LoadingComponent />
)
}
}
Upvotes: 0
Reputation: 5402
Loading flag is the right way to go. Give it a thought from the user's perspective. What should the user be seeing until the async call is done. Whatever that is, should be rendered during the fetch phase. Hence there are three possibilities for the component UI:
So yes, you need to add one more flag to maintain more than 2 states.
Upvotes: 2