React / Redux - Getting variable to update properly on change of global state

Viewed 240

I currently have a component (A) that has many local state variables, and also uses useSelector((state) => state.app.<var>. Some of the local state variables rely on that global state, and I need to render one local variable onto the screen.

code example:

const ComponentA = () => {
  const globalState = useSelector((state) => state.app.globalState);

  // CASE 1: WORKS
  const localState1 = 'hello' + globalState + 'world';

  // CASE 2: DOESN't WORK
  const [localState1, setLocalState1] = useState(null);
  const [lcoalState2, setLocalState2] = useState(null);


  useEffect(() => {
    
  }, [localState1]);

  useEffect(() => {
    setLocalState1('hello' + globalState + 'world')
  }, [localState2]);

  return (
    .... code changes 
    <p>{localState1}</p>
  );
}

Case 1 results in the localState1 properly being updated and rendered on the screen, but in Case 2 localState1 is not updated on the screen.

I have no idea why setting localState1 to a regular variable instead of a local state variable works. I thought that a change in local state would cause a re-render on the DOM, meaning I could visually see the change. Could someone explain why the local state case fails to update and how to fix it?

1 Answers

You need to make your useEffect aware of globalState change by adding it to dependencies array (anyway you should get a linting warning when you forget it, like in your case):

const ComponentA = () => {
  const globalState = useSelector((state) => state.app.globalState);

  const [localState1, setLocalState1] = useState(null);

  useEffect(() => {
    setLocalState1("hello" + globalState + "world");
  }, [globalState]);

  return <p>{localState1}</p>;
};

Moreover, you don't really need a state for it, just implement the selector according to your needs, it always will update on state.app.globalState change:

const ComponentA = () => {
  const globalStateString = useSelector(
    (state) => `hello ${state.app.globalState} world`
  );

  return <p>{globalStateString}</p>;
};
Related