1

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.

1
  • You probably want a loading indicator. Commented Nov 29, 2018 at 18:27

2 Answers 2

2

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:

  • During fetch phase
  • After fetch phase - ProductView
  • After fetch phase - Redirect

So yes, you need to add one more flag to maintain more than 2 states.

Sign up to request clarification or add additional context in comments.

1 Comment

Good points. I was curious if React had a built in way to defer rendering, but now I think this method makes more sense anyways. Thanks!
0

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 />
    )
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.