2

I cannot understand the difference between useState and useEffect. Specifically, the difference between state and lifecycle methods. For instance, I have watched tutorials and seen this example for useEffect:

const UseEffectBasics = () => {
  const [value, setVal] = useState(0);
  const add = () => {
    setVal((x) => { return x + 1 })
  }
   useEffect(() => {
    if (value > 0) {
      document.title = `Title: ${value}`
    }
   },[value])
  return <>
    <h1>{value}</h1>
    <button className="btn" onClick={add}>add</button>
  </>;
};

When we click the button, the title of the document shows us increasing numbers by one. When I removed the useEffect method and did this instead:

const UseEffectBasics = () => {
  const [value, setVal] = useState(0);
  document.title = `Title: ${value}`
  const add = () => {
    setVal((x) => { return x + 1 })
  }
  return <>
    <h1>{value}</h1>
    <button className="btn" onClick={add}>add</button>
  </>;
};

It worked same as the previous code. So, how does useEffect actually work? What is the purpose of this method?

P.S. Do not send me links of documentation or basic tutorials, please. I have done my research. I know what I am missing is very simple, but I do not know what is it or where to focus to solve it.

1 Answer 1

2

Using useEffect to track stateful variable changes is more efficient - it avoids unnecessary calls by only executing the code in the callback when the value changes, rather than on every render.

In the case of document.title, it doesn't really matter, since that's an inexpensive operation. But if it was runExpensiveFunction, then this approach:

const UseEffectBasics = () => {
  const [value, setVal] = useState(0);
  runExpensiveOperation(value);

would be problematic, since the expensive operation would run every time the component re-renders. Putting the code inside a useEffect with a [value] dependency array ensures it only runs when needed - when the value changes.

This is especially important when API calls that result from state changes are involved, which is pretty common. You don't want to call the API every time the component re-renders - you only want to call it when you need to request new data, so putting the API call in a useEffect is a better approach than putting the API call in the main component function body.

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

4 Comments

So, if we do not take on count the performance problems, can we skip using useEffect for side effect controlling? For ex, using private and component based data updating without useState (or state in class components) is not possible, as I understood.
Saving values across renders isn't impossible without state, but it's less common and harder to work with. Even if the operation is inexpensive, I don't think running it regardless is so elegant. I'd prefer to run it only when necessary (makes the intent of the code clearer) - or, even better, perform the action when updating the state, if feasable, rather than using useEffect or putting the code in the function body.
Really, you hit the point above, would you mind to share some video/text based tutorial where I can understand more deeper about lifecycle/useEffect methods? Stones still not placed on my brain about this topic.
The only tutorial I've really looked at is the official FAQ: reactjs.org/docs/hooks-effect.html reactjs.org/docs/hooks-state.html

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.