处理嵌套的上下文提供者
Posted
技术标签:
【中文标题】处理嵌套的上下文提供者【英文标题】:Handle Nested Context Providers 【发布时间】:2020-08-20 13:38:17 【问题描述】:我的应用中有几个嵌套的上下文提供程序,看起来像这样
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>
);
;
我确定这是一种不好的做法,但我不确定如何处理。我希望能够为所有上下文创建一个上下文提供程序。
【问题讨论】:
这不是一个坏习惯。事实上,如果您使用带有状态和调度上下文的减速器,您可能需要进一步分解它们。需要注意的是,如果我们的组件只需要例如字体上下文值,它不应该在 lang-context 更新时重新渲染。所以最好分解上下文。但是,您可能希望对上下文进行逻辑分组。例如,您提到的所有内容似乎都属于单个主题上下文 【参考方案1】:您可以简单地使用单个提供程序并将所需的值作为对象传递:
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)
....
【讨论】:
人们使用多个提供商是有原因的!例如只有那些提供者value
已更改的消费者才会重新呈现。使用您当前的语法是所有时间(问题代码具有相同的问题),例如使用useMemo
或像这里这样的单独状态:reactjs.org/docs/context.html#caveats【参考方案2】:
我想这很好,我也得到了很多Context
。但这并不理想,应用程序的结构也很差。
我建议阅读 Kent C. Dodds 的 Application State Management,其中讨论了 Context
,prop-drilling 的问题,然后还阅读 points to a Youtube-video,它解释了 组件组成 ,我认为这是一个很好的设计模式,从长远来看可能会导致需要更少的 Context
和更好的管理状态。
我也推荐阅读How to use React Context effectively
【讨论】:
以上是关于处理嵌套的上下文提供者的主要内容,如果未能解决你的问题,请参考以下文章