Can I use the React Context API inside a Context API or do I have to merge them?
Asked Answered
M

4

8

I am just curios about if it would be possible to use the Context API inside a Context API. Like for example I would have a Context API for an AppState and want to use that in another Context API which handles a WebSocket connection?

Mikelmikell answered 11/10, 2019 at 8:46 Comment(0)
M
6

Inspired by Joseph's answer I am thinking about just using those both context api's in a custom hook together.

useMultipleContexts(){
  const contextOne = useContext(ContextOne);
  const contextTwo = useContext(ContextTwo);

  /**
   * Do something with both contexts
   * in a custom hook that can be used
   * multiple times with the same state
   */


}

Mikelmikell answered 11/10, 2019 at 9:13 Comment(0)
R
5

This is a good scenario to use hooks instead of context.

// custom hook
function useAppState() {
  //add handlers here

  return appState;
}

function WebSocket() {
  const appState = useAppState();

  // do something (i.e reconnect) every time appState changes
  useEffect(() => { /* do something */, [appState])
}

function App() {
  return <WebSocket />
}
Ramses answered 11/10, 2019 at 8:53 Comment(3)
The appState as well as the state of the Websocket connections need to be global in the whole application. As longer as I think about it I guess the best thing is to make two seperate context api's and use both of them in a custom hook.Mikelmikell
So I would not say instead but with the context api togetherMikelmikell
@Mikelmikell sure that works. keep in mind to differentiate side-effects vs provided values.Ramses
P
2

Let me explain how to use two different Contexts at the same time.

First step: You need to create two different context

const AppContext = React.createContext(null);
const SocketContext = React.createContext(null);

Second step: You need to implement your custom hook.

const UseSharedLogic = () => {
   // your common logic
}

Then share it using the context API.

 <AppContext.Provider value={state}>
        <SocketContext.Provider value={UseSharedLogic}>
          <App />
        </DispatchContext.Provider>
      </StateContext.Provider>

Third step: You need to consume these contexts at the component that you need to use them inside it.

const state = React.useContext(AppContext);
const socket = React.useContext(SocketContext);

Here you can use both contexts together and you use one value from one context in another one.

Let's assume that socket context has a function called connect and it depends on value from the app context, you can do something like this.

socket.connect(state.anyValue);
Paludal answered 11/10, 2019 at 9:20 Comment(4)
I guess I have to improve writing my questions. I am more concerned about sharing that logic I would do with the two contexts all other the app and also create a new globale state with those both contexts I want to share as well.Mikelmikell
How you would like to share logic between two contexts? Context API: provides a way to pass data through the component tree without having to pass props down manually at every level. You can but the logic inside it. you can just use it to pass this logic from component to another component. if you want to share a logic you need to implement a custom hook.Paludal
So would I rather use the custom hook then inside the context api and pass it down this way or use the context api inside of a hook and use that multiple times? I mean in the second scenario I could use more than one context with the shared logic.Mikelmikell
Yes, exactly. I edited my answer, have a look again.Paludal
L
0

I would create a new functional component that would wrap the components

Say you had two components written as follows.

import React from 'react';
const ContextA = React.createContext({});
export default ContextA;
import React from 'react';
const ContextB = React.createContext({});
export default ContextB;

I generally avoid the above pattern because people have to guess what you're trying to put in the context. Instead I write a functional component that provides the context as follows

import { createContext, useContext } from 'react'
import ContextA from './contexta'
import ContextB from './contextb'

// The ! is needed in order to allow undefined to be set as the initial value.
const MyContext = createContext<IMyContextInfo>(undefined!);
export default ({children}) => {
  const { somethingFromA } = useContext(ContextA);
  const { somethingFromB }= useContext(ContextB);
  return (
    <MyContext.Provider value={{ a: somethingFromA, b: somethingFromB }}>
      {children}
    </MyContext.Provider>
  );
}
Limassol answered 2/2, 2021 at 19:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.