Обработка поставщиков вложенного контекста - PullRequest
2 голосов
/ 05 мая 2020

У меня есть несколько вложенных поставщиков контекста в моем приложении, которые выглядят так:

export const LangContext = React.createContext("javascript");
export const FontContext = React.createContext("mono-space");
export const FontSizeContext = React.createContext("16px");

const Store = ({ children }) => {
  const [lang, setLang] = useState("javascript");
  const [font, setFont] = useState("mono-space");
  const [fontSize, setFontSize] = useState("16px");
  return (
      <LangContext.Provider value={[lang, setLang]}>
        <FontContext.Provider value={[font, setFont]}>
          <FontSizeContext.Provider value={[fontSize, setFontSize]}>
              {children}
          </FontSizeContext.Provider>
        </FontContext.Provider>
      </LangContext.Provider>
  );
};

Я уверен, что это плохая практика, но я не уверен, как с этим справиться. Я хочу иметь возможность создать единого поставщика контекста для всех контекстов.

1 Ответ

1 голос
/ 05 мая 2020

Вы можете просто использовать одного провайдера и передавать требуемые значения как объект

export const StoreContext = React.createContext({});
const Store = ({ children }) => {
  const [lang, setLang] = useState("javascript");
  const [font, setFont] = useState("mono-space");
  const [fontSize, setFontSize] = useState("16px");
  return (
      <StoreContext.Provider value={{lang, setLang, font, setFont, fontSize, setFontSize}}>
              {children}
      </StoreContext.Provider>
  );
};

Также вместо использования useState вы можете изменить приведенное выше, чтобы использовать useReducer и сделать его еще более простым API

const initialState= {
   lang: 'javascript',
   font: 'mono-space',
   fontSize: '16px',
}

const reducer = (state, action) => {
    switch (action.type) {
        case 'SET_LANG': return {...state, lang: action.payload}
        case 'SET_FONT': return {...state, font: action.payload}
        case 'SET_FONTSIZE': return {...state, fontSize: action.payload}
        default: return state;
    }
}
export const StoreContext = React.createContext({});
const Store = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
      <StoreContext.Provider value={[state, dispatch]}>
              {children}
      </StoreContext.Provider>
  );
};

а в детском можно использовать как

const Child = () => {
    const [state, dispatch] = useContext(StoreContext);
    const handleChange = (size) => {
         dispatch({type: 'SET_FONTSIZE', payload: size})
    }
    ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...