3

So I am setting my state in my constructor with:

constructor(props: IProps) {
    super(props);
    const nav = NavService.getNav();
    const user = AuthService.getProfile();

    this.state = {
        activeNav: 0,
        nav: nav ? nav : [],
        showDropdown: false,
        showNavDropdown: false,
        user: user ? user : [],
    };
}

However, I am noticing some async issues so I want to make getNav() and getProfile() async and await them. Obviously I can't do this in the constructor because constructors cannot be async and therefore I cannot use await. Now I know I can just throw this into an async componentDidMount() but this causes a double render(). How can I optimize this?

1
  • 2
    Preload data before mounting a component at all (render null or a placeholder)? Commented Jul 5, 2018 at 19:03

1 Answer 1

4

I think a re-render will be hard to avoid if your have to load some data asynchronously.

You could keep an additional state variable loading and just return null in the render method until your data has loaded.

Example

class App extends React.Component {
  state = {
    activeNav: 0,
    nav: [],
    showDropdown: false,
    showNavDropdown: false,
    user: [],
    loading: true
  };

  componentDidMount() {
    Promise.all(NavService.getNav(), AuthService.getProfile())
      .then(([nav, user]) => {
        this.setState({ nav, user, loading: false });
      })
      .catch(error => {
        this.setState({ loading: false });
      });
  }

  render() {
    const {
      activeNav,
      nav,
      showDropdown,
      showNavDropdown,
      user,
      loading
    } = this.state;

    if (loading) {
      return null;
    }

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

2 Comments

Yeah this looks like the best way to do it. Thanks!
What I ended up doing was have componentDidMount be an async function and then in render if (nav && user) return my component, otherwise return null. Works great.

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.