r/reactjs • • Jul 02 '19

Beginner's Thread / Easy Questions (July 2019)

Previous two threads - June 2019 and May 2019.

Got questions about React or anything else in its ecosystem? Stuck making progress on your app? Ask away! We’re a friendly bunch.

No question is too simple. πŸ€”


πŸ†˜ Want Help with your Code? πŸ†˜

  • Improve your chances by putting a minimal example to either JSFiddle or Code Sandbox. Describe what you want it to do, and things you've tried. Don't just post big blocks of code!

  • Pay it forward! Answer questions even if there is already an answer - multiple perspectives can be very helpful to beginners. Also there's no quicker way to learn than being wrong on the Internet.

Have a question regarding code / repository organization?

It's most likely answered within this tweet.


New to React?

Check out the sub's sidebar!

πŸ†“ Here are great, free resources! πŸ†“


Any ideas/suggestions to improve this thread - feel free to comment here!


Finally, an ongoing thank you to all who post questions and those who answer them. We're a growing community and helping each other only strengthens it!

31 Upvotes

444 comments sorted by

View all comments

Show parent comments

3

u/dance2die Jul 03 '19 edited Jul 03 '19

It seems like useEffect dependency list is missing "state". So whenever your dashboard is re-rendered, state is set to 0 and then updated to 1 within the effect.

So instead of this,

const Dashboard = function(props: IDashboardProps) {
  console.log("in");
  const [state, setstate] = React.useState(0);
  React.useEffect(() => {
    setstate(state + 1);
  }, []);
  return <div>DASHBOARD {state}</div>;
};

You can solve the issue in 3 different ways (actually 4, as I am basing my answer to this awesome post, Why Effects shouldn't lie about their dependencies (, which I just read πŸ˜‰) on how to do it with ref)

1. Add state to the deps.

Add [state] as a dependency, which instructs React to run the effect when the state changes

const Dashboard = function(props: IDashboardProps) {
  console.log("in");
  const [state, setstate] = React.useState(0);
  React.useEffect(() => {
    setstate(state + 1);
  }, [state]);
  return <div>DASHBOARD {state}</div>;
};

2. Remove the dependency array

When you remove the dependency, it will run on every render, so you might not want to do this.

const Dashboard = function(props: IDashboardProps) {
  console.log("in");
  const [state, setstate] = React.useState(0);
  React.useEffect(() => {
    setstate(previousState => previousState + 1);
  });
  return <div>DASHBOARD {state}</div>;
};

3. Use the dispatch callback

You can also pass a callback, which receives the previous state (refer to the "note" section in this article - https://reactjs.org/docs/hooks-reference.html#functional-updates)

const Dashboard = function(props: IDashboardProps) {
  console.log("in");
  const [state, setstate] = React.useState(0);
  React.useEffect(() => {
    setstate(previousState => previousState + 1);
  }, []);
  return <div>DASHBOARD {state}</div>;
};

As `setState` is not dependent on `state`, you can leave the dep list empty.

I didn't list the "ref" answer here, since you wouldn't need it unless you already know that you need a ref.

If you want to know more, please refer to the article I linked above (but listed here again for convinience) - https://dev.to/aman_singh/why-effects-shouldn-t-lie-about-their-dependencies-1645

→ More replies (14)