Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set state with same value using hooks will cause a rerender?

Using hooks, If I call setState with the same value as the state, will it rerender the component?

If yes, how can I avoid that?

e.g.

const [state, setState] = useState(foo)

...
// any where in the code
setState(foo)

Considering that foo can be any thing, such as {}, true, props.bar or a variable from out side of the component (constant).

like image 413
Vencovsky Avatar asked Dec 26 '19 14:12

Vencovsky


2 Answers

It won't re-render the component if you call setState with the same value.

Try this out:

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

const foo = { foo: 'bar' };

export default ({ name }) => {
  const [state, setState] = useState(foo);
  console.log("rendered!");
  useEffect(() => {
    setState(foo);
    console.log("state reset!");
  });

  const handleClick = () => {
    console.log("handleClick!");
    setState(foo);
    // setState({ ...foo, bar : 'baz' });
  }

  return (<div>
  <h1>Hello {name}!</h1>
  <button onClick={handleClick}>Click Me</button>
  </div>);
};

You'll notice that even when the button is clicked since the value has not changed. it's not re-rendering the Component. If you change the argument that you call setState with, it will re-render the component.


Here's a Code Sample for your ref.

Try commenting the first setState and un-commenting the second one inside the handleClick method to see the difference.

like image 72
SiddAjmera Avatar answered Oct 27 '22 01:10

SiddAjmera


just to summarize

if your state is a primitive value(number, string, boolean, ...), then setting the same value using setState hook won't trigger a rerender. If your state is an Object or Array then it will behave differently.

https://overreacted.io/how-are-function-components-different-from-classes/
https://dmitripavlutin.com/value-vs-reference-javascript/

like image 33
Vlad Ryabinin Avatar answered Oct 27 '22 01:10

Vlad Ryabinin