How to access dispatch method of multiple contexts in React Context API hooks?

I have an app with multiple contexts:

class App extends Component {
  render() {
    return (
      <SettingsProvider>
        <ContentProvider>
          <Component />
        </ContentProvider>
      </SettingsProvider>
    );
  }
}

And I have set up Redux-like store with React Context API, with dispatch methods in reducers. My both provider are set up like this:

import reducer from './reducers';

export const SettingsContext = createContext();

function SettingsProvider({ children, userSettings }) {
  const [state, dispatch] = useReducer(
    reducer,
    _.merge(defaultSettings, JSON.parse(userSettings)),
  );

  return (
    <SettingsContext.Provider value={{ state, dispatch }}>{children}</SettingsContext.Provider>
  );
}

Now I need to access dispatch method of both providers from a component, but it throws an error... Please see a code with comments below:

function Settings() {
    // This works in most components, which need to access only one context
    const {state, dispatch} = React.useContext(ContentContext);

    // This method works for accessing multiple contxest
    const settings = React.useContext(SettingsContext);   // accessable as settings.state
    const content = React.useContext(ContentContext);     // content.state.

    // but now this is throwing an error that settings and dispatchSettings are undefined..
    const {settings, dispatchSettings} = React.useContext(SettingsContext);   // accessable as settings.state
    const {content, dispatchContent} = React.useContext(ContentContext);     // content.state.

}

What I am missing here?

Upvotes: 2

Views: 3748

Answers (2)

Niko
Niko

Reputation: 8153

You can use renaming with object destructuring e.g.

const { dispatch } = useContext(DefaultContext);
const { dispatch: altDispatch } = useContext(AltContext);

Dispatch for DefaultContext is now accessible with dispatch and AltContext with altDispatch.

Upvotes: 1

Umair
Umair

Reputation: 469

I believe you should have to rename the dispatch variable .

    function SettingsProvider({ children, userSettings }) {
       const [state, dispatchSettings] = useReducer(
       reducer,
       _.merge(defaultSettings, JSON.parse(userSettings)),
    );

    return (
      <SettingsContext.Provider value={{ state, dispatchSettings }}> 
          {children} 
      </SettingsContext.Provider>
          );

Same approach will be used for ContentProvider reducer.

Upvotes: 0

Related Questions