Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why setState hook is changing another state

I’m loading an array of data in my initial state of targets and in my state of dataBaseTargets, In my code I want to change the value of targets state and let the value of dataBaseTargets state unchanged after one useEffect call, but I’m encountering a problem, whenever I want to do this, the value of dataBaseTargets is changed by itself whenever I change the value of targets.

here is the sandbox of my code :

https://codesandbox.io/s/vigilant-cerf-kg2ej6?file=/src/App.js:0-963

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

    import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [targets, setTargets] = useState([]);
  const [dataBaseTargets, setDataBaseTargets] = useState([]);
  useEffect(() => {
    // A database call to get the dataBaseTargets and the initial value of targets
    const array = [1, 2, 3];
    setTargets(array);
    setDataBaseTargets(array);
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button
        onClick={() => {
          const _targets = targets;
          _targets.push(5);
          setTargets(_targets);
        }}
      >
        {" "}
        ADD AN ELEMENT
      </button>
      <br />
      <button
        onClick={() => {
          console.log(targets); // both lines print the same value!
          console.log(dataBaseTargets);
        }}
      >
        SHOW
      </button>
    </div>
  );
}

>Solution :

You are using the same array for both states, and then you mutate the array, and it reflects in both.

The const _targets = targets; doesn’t clone the original array. It’s just an alias to the same array. To clone it you should use something like array spread (see other methods) – const _targets = [...targets];

Example:

export default function App() {
  const [targets, setTargets] = useState([]);
  const [dataBaseTargets, setDataBaseTargets] = useState([]);
  useEffect(() => {
    // A database call to get the dataBaseTargets and the initial value of targets
    const array = [1, 2, 3];
    setTargets(array);
    setDataBaseTargets([...array]); // create a separate copy
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button
        onClick={() => {
          setTargets([...targets, 5]); // create new state with the added item
        }}
      >
        {" "}
        ADD AN ELEMENT
      </button>
      <br />
      <button
        onClick={() => {
          console.log(targets);
          console.log(dataBaseTargets);
        }}
      >
        SHOW
      </button>
    </div>
  );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading