associate a state with another state in useState hook
Asked Answered
I

2

8

I want to have a state B that its value is dependent to sate A and when state A value updated, state B value updates subsequently.

The problem is as @Atin Singh stated here changing multiple states in react js useState() hook

const [x, setX] = useState(0)
const [y, setY] = useState(x) // this is just to initialize an initial value to your state y so it will be once set to the value of x and then it doesn't depends on x//

State B value initialized to state A value and doesn't depends on value of state A.

But is there any way to make state B value dependent on state A value?

Here is the simplified code:

export default function App() {
  const [a, setA] = useState("");
  const [b, setB] = useState(a);

  const updateA = () => {
    setA("Hi");
  };

  useEffect(() => {
    console.log("a: ", a);
    console.log("b: ", b);
  });

  return (
    <div className="App">
      <button onClick={updateA}>Update State A</button>
    </div>
  );
}

you can edit the code from here: https://codesandbox.io/s/nifty-sun-ml843?fontsize=14&hidenavigation=1&theme=dark

Instructive answered 3/5, 2020 at 3:11 Comment(0)
P
8

you can use useEffect with Dependency as [a]. Add this block, so when ever a gets updated , this useEffect will run and set the value of B

   useEffect(() => {
        setB(a);
      },[a]);

complete Code:

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

export default function App() {
  const [a, setA] = useState("");
  const [b, setB] = useState(a);

  const updateA = () => {
    setA("Hi");
  };

  useEffect(() => {
    setB(a);
  },[a]);

  useEffect(() => {
    console.log("a: ", a);
    console.log("b: ", b);
  });

  return (
    <div className="App">
      <button onClick={updateA}>Update State A</button>
    </div>
  );
}

Output:

a:  "" 
b:  "" 
a:  Hi 
b:  "" 
a:  Hi 
b:  Hi 
Paperboy answered 3/5, 2020 at 3:17 Comment(3)
Wouldn't this result in a loop ? Since he needs both state to update subsequently. B updates A, then your effect with deps is triggered and update B, then B updates A etc.Fayfayal
That's right but it re-evaluate whole of state B value each time state A value changed. For example lets think state B = A + "World", I want to recalculate only A part.Instructive
No it will not get into loop, OP wants state of B dependent of A and not both wise. This usestate will be called additionally after value of a is setPaperboy
K
3

If b is fully derived from a and doesn't need to be set separately you can use useMemo hook:

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

export default function App() {
  const [a, setA] = useState("");
  const b = useMemo(() => a, [a]);

  const updateA = () => {
    setA(`Hi, time is ${new Date()}`);
  };

  useEffect(() => {
    console.log("a: ", a);
    console.log("b: ", b);
  });

  return (
    <div className="App">
      <button onClick={updateA}>Update State A</button>
    </div>
  );
}
Koala answered 19/1, 2023 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.