Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

357
Views
React useState rerender even if i pass the same reference?

What I know is that useState will not rerender if we pass the same state, and I test it by myself, but it worked only the first time the component rerendered, with an initial state passed to useState. But in the example below, the useState rerenders the component even if I pass the same reference, also useEffect knows that the state does not changed. The picture with console.logs shows that behavior.

const arr = [
  { name: 'Khaled', id: 0 },
  { name: 'Mohamed', id: 1 },
  { name: 'Ahmed', id: 2 },
  { name: 'Mohsen', id: 3 },
];

function App() {
  console.log('num $1');

  const [same, setSame] = useState({});

  useEffect(() => {
    console.log('num $3');

    const test = arr.find((el) => el.id === 0);
    console.log(Object.is(same, test));
    setSame(test);
  }, [same]);

  console.log('num $2');

  return <div>welcome</div>;
}

enter image description here

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

The component is rendered twice because you have the initial value for the same state which is empty { }. inside the useEffect you update this state with a new object then the useEffect triggers a new value that has been added to the same state. which is the matched object from your array. then the component re-rendered and that's why you got in the console.log the true value.

   const arr = [
      { name: 'Khaled', id: 0 },
      { name: 'Mohamed', id: 1 },
      { name: 'Ahmed', id: 2 },
      { name: 'Mohsen', id: 3 },
    ];
    
    function App() {
      console.log('num $1');
    
      const [same, setSame] = useState({}); <= initial value
    
      useEffect(() => {
        console.log('num $3');
    
        const test = arr.find((el) => el.id === 0);
        console.log(Object.is(same, test)); <= changed from false to true because the new value of same
        setSame(test); <= you updated the state
      }, [same]); <= the value of same changed from { } to a new value and that's make the component to re-render
    
      console.log('num $2');
    
      return <div>welcome</div>;
    }

That's an update for your last comment.

import { useState, useEffect } from "react";

const arr = [
  { name: "Khaled", id: 0 },
  { name: "Mohamed", id: 1 },
  { name: "Ahmed", id: 2 },
  { name: "Mohsen", id: 3 }
];

export default function App() {
  const [same, setSame] = useState(arr);

  useEffect(() => {
    const test = arr.find((el) => el.id === 0);
    console.log(same); <= here the same is [] with 4 objecs
    setSame(test);
    console.log(same); <= here the same is { }
  }, [same]);

  return <div>welcome</div>;
}

with that. this will lead us that the useEffect once it sees the same get updated. then it will re-render the component as I mentioned before.

here same have the same data. but they are different because the first same is [] and the second one is { }. so that's a change in the state. then useEffect will re-render.

about 4 years ago · Juan Pablo Isaza Report

0

Previous answer explains it perfectly. To not have the state re-render you must initialize it with the original array.

const arr = [
  { name: 'Khaled', id: 0 },
  { name: 'Mohamed', id: 1 },
  { name: 'Ahmed', id: 2 },
  { name: 'Mohsen', id: 3 },
];

function App() {
  console.log('num $1');

  const [same, setSame] = useState(arr); <= initial value is now original arr

  useEffect(() => {
    console.log('num $3');

    const test = arr.find((el) => el.id === 0);
    console.log(Object.is(same, test)); <= changed from false to true because the new value of same
    setSame(test); <= you updated the state
  }, [same]); <= the value of same changed from { } to a new value

  console.log('num $2');

  return <div>welcome</div>;
}

Make note that this only works for the reference types. Hook doesn’t perform a comparison on objects or arrays, it simply checks whether the reference changes or not. This does not work for value types.

about 4 years ago · Juan Pablo Isaza Report

0

I'm slightly confused on what exactly you are trying to do, but here's my understanding of this and hopefully an answer to your problem.

Its important to remember that a useEffect() will be called on component mount (first render) no matter what. This is why your component is spitting out the num $3 console log on first render, even though logically you would expect it not to run at-all, as the only setSame() function is within the useEffect() itself.

For the reason the component re-renders after the state is set with a seemingly-identical object, another important thing to remember here (and with JavaScript in general) is referential equality. Consider the following:

{} === {} //false

Even though logically, you would expect two identical objects to evaluate as two equals, as far as JavaScript is concerned, they are not the same. So, when you pass an object into the setSame() function that looks the same as what the same state is at that time, JavaScript considers it a change of state and prompts a re-render in React.

Hope this helps.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!