Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react hook for multiple component state didn't update

I have a hook, and 2 components. Component App.js has a function that changes the state in hook, but the value is not updated in Component New.js, why? I think I've missed something but can't figure it out.

App.js

export const useToggle = () => {
  const [onOff, setOnOff] = useState(false);
  return [onOff, () => setOnOff((prev) => !prev)];
};

export default function App() {
  const [onOff, setOnOff] = useToggle();

  return (
    <div className="App">
      <h1>{onOff.toString()}</h1>
      <button onClick={setOnOff}>toggle</button>
    </div>
  );
}

New.js

import { useToggle } from "./App.js";

export default function New() {
  const [onOff] = useToggle();

  return (
    <div className="App">
      <hr />
      <h1>NEW:</h1>
      <pre>{onOff.toString()}</pre>
    </div>
  );
}

https://codesandbox.io/s/musing-fire-rjude?file=/src/App.js

like image 862
alice_morgan Avatar asked May 22 '26 01:05

alice_morgan


1 Answers

Each useToggle hook is its own entity with its own state. The useToggle that you are toggling in App isn't the same useToggle that is rendered/used in New.

This means they are toggled independently of any other hooks and state. They don't share "state".

If you are wanting to create a useToggle hook that does have shared state then I would suggest implementing it via a React context and the useContext hook so each useToggle hook can toggle the same shared state held in the context.

Update

Global useToggle hook.

togglecontext.js

import { createContext, useContext, useState } from 'react';

export const ToggleContext = createContext([false, () => {}]);

const ToggleProvider = ({ children }) => {
  const [onOff, setOnOff] = useState(false);
  const toggle = () => setOnOff(t => !t);

  return (
    <ToggleContext.Provider value={[onOff, toggle]}>
      {children}
    </ToggleContext.Provider>
  );
}

export const useToggle = () => useContext(ToggleContext);

export default ToggleProvider;

index - provide the context

...
import ToggleProvider from "./toggle.context";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <ToggleProvider>
      <App />
      <New />
    </ToggleProvider>
  </StrictMode>,
  rootElement
);

App

import "./styles.css";
import { useToggle } from "./toggle.context";

export default function App() {
  const [onOff, setOnOff] = useToggle();

  return (
    <div className="App">
      <h1>{onOff.toString()}</h1>
      <button onClick={setOnOff}>toggle</button>
    </div>
  );
}

New

import { useToggle } from "./toggle.context";

export default function New() {
  const [onOff] = useToggle();

  return (
    <div className="App">
      <hr />
      <h1>NEW:</h1>
      <pre>{onOff.toString()}</pre>
    </div>
  );
}

Edit react-hook-for-multiple-component-state-didnt-update

Note that the only thing that changed in the App and New components was the import, where the useToggle hook is defined.

like image 161
Drew Reese Avatar answered May 24 '26 15:05

Drew Reese



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!