Home > Blockchain >  UseEffect without second parameter Vs not using useEffect
UseEffect without second parameter Vs not using useEffect

Time:06-26

In the reactjs UseEffect documentation, we find below code where the document.title is updated using the useEffect hook

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count   1)}>
        Click me
      </button>
    </div>
  );
}

export default App;

I am trying to understand the difference between using the useEffect hook without passing the second argument ( like [] for mount only) and just using the code to update the title (or any other code) outside without using the hook.

import { useState, useEffect } from 'react';
function App() {
  const [count, setCount] = useState(0);
  document.title = `You clicked ${count} times`;
  // useEffect(() => {
  //   document.title = `You clicked ${count} times`;
  // });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count   1)}>
        Click me
      </button>
    </div>
  );
}

export default App;

What is the difference?

CodePudding user response:

The answer clearly lies in another question. The question is when does useEffect run in a react application?

React official docs/team says that useEffect is a way to lets us perform our sideffects after the first render and every other subsequent render.

So, in your second example, the real dom is manipulated at first render too. This will throw an error in case the dom node is not painted to the screen. Luckily, your second example will not throw an error because the document.title will be going to be loaded (default behavior of webpage).

That's why all folks recommend us to do dom-manipulation inside the useEffect.

CodePudding user response:

The main difference is The function passed to useEffect will run after the render is committed to the screen

import { useState, useEffect } from 'react';
function Bla() {
  const [count, setCount] = useState(0);
  console.log(`You clicked ${count} times before render `) // before the render phase
  useEffect(() => {
    console.log(`You clicked ${count} times after render `) //after render phase
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count   1)}>
        Click me
      </button>
    </div>
  );
}

export default Bla;

CodePudding user response:

The first line from the docs says :

The Effect Hook lets you perform side effects in function components.

A simple definition of side effect is an action that performs something that might not be predictable. Setting storage, changing DOM etc. Your action of changing the title is a side effect. A good SO link

Any code outside event handlers and hooks definition will run on every render. So, if you write your title changing statement it will run on every render. Now, you do not want to update the title in every render. You want it to execute after the DOM has been painted and render cycle is complete. For which you have useEffect. With useEffect you have control on that. The below code will run after every render.

useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

Ideal because the UI is not affected by this action, and there is no need for it to be included in the code that is determining the output(UI) you have to show.

  • Related