React Hooks Async Best Practice

Now with use useEffects, there is a substitute for componentDidMount into a React Component with Hooks.

Scenario "initial unique call to a server":

To accomplish this, DependencyList (second argument of useEffect) in useEffect should every time an empty array otherwise the application will send every state change a fetch call to the server.

it means, this is the best practice to getData

useEffect(() => {
  console.log("useEffect, fetchData here");
}, []);

Is it best practice, to use [] as DependencyList param to disable server requesting every state changing?

Link to github https://github.com/facebook/react/issues/14326

Answers:

Answer

Yes. This is the best approach.

From the react docs:

Passing in an empty array [] of inputs tells React that your effect doesn’t depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won’t run on updates.

useEffect is a very powerful, and my favorite, hook. You can monitor one or more variables for state changes by passing them into the second parameter array, or you can just listen for mounting and unmounting with the approach that you're using.

Answer

It depends on whether you want the server to be called whenever some parameter changes. If you want the same async call regardless, you can use [] as the second parameter.

However, if you are for example displaying a profile page of a user where each page has a userID state/prop, you should pass in that ID as a value into the second parameter of useEffect so that the data will be refetched for a new user ID. componentDidMount is insufficient here as the component might not need remounting if you go directly from user A to user B's profile.

In the traditional classes way, you would do:

componentDidMount() {
  this.fetchData();
}

componentDidUpdate(prevProps, prevState) {
  if (prevState.id !== this.state.id) {
    this.fetchData();
  }
}

With hooks, that would be:

useEffect(() => {
  this.fetchData();
}, [id]);

Try running the code below and see the result. Change the id to 2 for instance to see that useEffect is run again.

function Todo() {
  const [todo, setTodo] = React.useState(null);
  const [id, setId] = React.useState(1);
  
  React.useEffect(() => {
    if (id == null || id === '') {
      return;
    }
    
    fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
      .then(results => results.json())
      .then(data => {
        setTodo(data);
      });
  }, [id]); // useEffect will trigger whenever id is different.

  return (
    <div>
      <input value={id} onChange={e => setId(e.target.value)}/>
      <br/>
      <pre>{JSON.stringify(todo, null, 2)}</pre>
    </div>
  );
}

ReactDOM.render(<Todo />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

You should read up on useEffect so that you know what you can/cannot do with it.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.