1
\$\begingroup\$

I created a boilerplate from react-boilerplate. I have removed redux and immutable for use context API and immer.

I wonder if I use the context API with a good design pattern.

I use like this:

// ./app/containers/LanguageProvider/index.js
import React from 'react';
import PropTypes from 'prop-types';
import { IntlProvider } from 'react-intl';
import {
  Context as ContextLanguageProvider,
  Consumer as ConsumerLanguageProvider,
} from './Context';

export const LanguageProvider = props => {
  const { children, messages } = props;

  return (
    <ContextLanguageProvider>
      <ConsumerLanguageProvider>
        {ctx => (
          <IntlProvider
            locale={ctx.state.locale}
            key={ctx.state.locale}
            messages={messages[ctx.state.locale]}
          >
            {React.Children.only(children)}
          </IntlProvider>
        )}
      </ConsumerLanguageProvider>
    </ContextLanguageProvider>
  );
};

LanguageProvider.propTypes = {
  messages: PropTypes.object,
  children: PropTypes.element.isRequired,
};

export default LanguageProvider;

and I created the context API like this:

// ./app/containers/LanguageProvider/Context.js
import React from 'react';
import PropTypes from 'prop-types';

import { initialState, reducer } from './reducer';

const { Provider, Consumer } = React.createContext('languageProvider');

export const Context = props => {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  const { children } = props;

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

Context.propTypes = {
  children: PropTypes.element.isRequired,
};

export { Consumer };

Here the reducer.js and actions.js:

// ./app/containers/LanguageProvider/reducer.js
/* eslint-disable consistent-return,no-param-reassign */
import produce from 'immer';
import { CHANGE_LOCALE } from './constants';
import { DEFAULT_LOCALE } from '../../i18n';

export const initialState = {
  locale: DEFAULT_LOCALE,
};

export const reducer = (state = initialState, action) =>
  produce(state, draft => {
    switch (action.type) {
      case CHANGE_LOCALE:
        draft.locale = action.locale;
        break;
      default:
        return state;
    }
  });




// ./app/containers/LanguageProvider/actions.js
import { CHANGE_LOCALE } from './constants';

export function changeLocale(languageLocale) {
  return {
    type: CHANGE_LOCALE,
    locale: languageLocale,
  };
}

I would like to know your reviews on my strategy and how to optimize.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.