1

I need to share global variables through multiple components, and it seems that my context is not working as expected.

I declared in a seperated file globalContext.tsx :

export type GlobalContent = {
  entities: entity[]
  setEntities:(c: entity[]) => void,
  pallets: string[],
  setPallets:(c: string[]) => void,
}
export const GlobalContext = createContext<GlobalContent>({
    entities: [], // set a default value
    setEntities: () => {},
    pallets: [],
    setPallets: () => {}
})

Then, initialize and my values in my App.tsx, then wrapping all my tree in the Provider :

function App() {
  // Init global variables, accessible everywhere using useContext hook
  const [entities, setEntities] = useState<entity[]>([])
  const [pallets, setPallets] = useState<string[]>(["hello"])
  let defaultGlobals: GlobalContent = { entities, setEntities, pallets, setPallets }

  return (
    <GlobalContext.Provider value={defaultGlobals}>
      <BrowserRouter>
        <Routes>
            <Route path="/" element={<Home/>}/>
            <Route path="/picking" element={<Picking/>}/>
            <Route path="/control" element={<Control/>}/>
            <Route path="/place" element={<Place/>}/>
            <Route path="*" element={<NotFound/>}/>
        </Routes>
      </BrowserRouter>
    </GlobalContext.Provider>
  )
}

So, there should be it. Within my components (let's say <Picking/> for example), I can get find back my default values by using the following :

const { entities, setEntities, pallets, setPallets } = useContext(GlobalContext)

But when I grab this data in another component (<Control/> or <Place/>) using :

const { entities, setEntities, pallets, setPallets } = useContext(GlobalContext)

I keep getting the default value (a.k.a. the "defaultGlobals", with ["hello"] array).

I tried changing my entities or pallets content using the corresponding setters, and the variables extracted from the useContext are definitively independant from a component to another. Still getting default values at first.

Seems something is breaking the context or I am doing something wrong here. Any help ?

Here's a link to a running codesandbox.

Example consumer:

export default function Home() {
  const { entities, setEntities, pallets, setPallets } = useContext(
    GlobalContext
  );

  return (
    <div>
      <a href="/other">Move to Other</a>
      <h1>Home component</h1>
      <button onClick={() => setPallets([...pallets, "newPallet"])}>
        Add pallet
      </button>
      {pallets.map((pallet) => {
        return <p>{pallet}</p>;
      })}
    </div>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Bababibel
  • 13
  • 3
  • `["hello"]` is the default `pallets` state value, so why *wouldn't* another context consumer see that value? I don't see any issue with the code you've shared so I'm thinking if you are seeing something unusual/unexpected it is occurring elsewhere. Can you more clearly explain the perceived issue and exact steps to reproduce, and what you are expecting to see? – Drew Reese Apr 04 '22 at 21:23
  • Sorry if it is not clear. My objective here is to use global variables using context. My component is pushing data in the `pallets` and `entities` variables (using the corresponding useState setters). Tell me if I am wrong, but for me, I should be able to see these data in my other components, due to the sharing context. But in my other components, I keep getting the default value and I am not able to see any modification the "global variables" – Bababibel Apr 05 '22 at 10:15
  • Yes, that is correct. I don't see any overt issue(s) with the code you've shared though. Could you try to create a *running* codesandbox demo that reproduces this issue that we could inspect and debug live? – Drew Reese Apr 05 '22 at 15:21
  • Yes of course ! Here is a link : https://codesandbox.io/s/practical-sky-jlud9m?file=/src/App.tsx I created 2 very basic components grabbing the global context, editing data and displaying it. Thanks for your time :) – Bababibel Apr 05 '22 at 16:47

1 Answers1

0

The pallets state and React context value are updating just fine. The issue is that you are using raw anchor tags (<a />) to navigate between pages and this is reloading the entire page/app. In other words, the app is remounted and React state is reset.

Use the Link component to issue declarative navigation actions to move around the app.

Instead of this:

<a href="/other">Move to Other</a>

Import and use the Link component:

import { Link } from "react-router-dom";

...

<Link to="/other">Move to Other</Link>

Edit react-usecontext-always-returning-initial-value-in-different-children

enter image description here enter image description here enter image description here

Drew Reese
  • 165,259
  • 14
  • 153
  • 181