Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does React.createContext create multiple instances from a singe context?

Consider my example:

const itemStructure = {
  a: [ "d", "c" ],
  b: [ "e", "f" ]
};

const Context = React.createContext({
  setId: () => {}, getId: null, providerId: null
});

const InnerItem = ({ id }) => {
  const value = React.useContext(Context);
  const setItem = () => value.setId(id);

  console.log(value);

  return <button onClick={setItem}>{id}</button>;
};

const OuterItem = ({ providerId }) => {
  const [ getId, setId ] = React.useState(null);

  return (
    <Context.Provider value={{ getId, setId, providerId }}>
      {itemStructure[providerId].map(id => <InnerItem id={id} key={id} />)}
    </Context.Provider>
  );
};

const App = () => {
  return Object.keys(itemStructure).map(id => (
    <OuterItem providerId={id} key={id} />
  ));
};

ReactDOM.render(<App />, document.getElementById('root'));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

See what the console logs after each button click as providerId. It logs the right values, but I can't understand why. I'd expect that it doesn't work as no matter which OuterItem uses it, it will be the same Context, and they share on it.

So my question is how multiple components can share on the same context, but make it identical by the Provider?

like image 429
Gergő Horváth Avatar asked May 21 '26 01:05

Gergő Horváth


1 Answers

When you call the createContext, you aren't create a instance, you only create a new type of context.

So when you call <TypeContext>.Provider you are creating a instance to all components are inside this context instance of this type. So whatever component that use this context, ever find the context type more near.

So some examples:

const OneTypeContext = React.createContext('hello world')
const WorldOne = () => {
  const value = useContext(OneTypeContext)

  console.log(value)
}
<OneTypeContext.Provider>
  <WorldOne />
</OneTypeContext.Provider>

// console.log(value) => `hello world`

But if you put the same context type as new instance inside other instance of same context, the function like useContext will find the context nearly. Ex:

<OneTypeContext.Provider>
  <OneTypeContext.Provider value="Hello Other World">
    <WorldOne />
  </OneTypeContext.Provider>
</OneTypeContext.Provider>

// console.log(value) => `Hello Other World`

Reference: https://reactjs.org/docs/context.html#api

like image 78
Fuechter Avatar answered May 22 '26 15:05

Fuechter



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!