context
const MyContext = React.createContext(defaultValue);
<MyContext.Provider value={/* 某个值 */}>
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
const value = useContext(MyContext);
// 相当于直接获取到 value
例子
明显属于全局层面
组件库的主题。其实最本质的就是一个 theme object 嘛,简单做法:
- 用户直接初始化组件库的时候传入
- 放在 css variable 里,编译的时候覆盖
上述最主要的问题是不能实现动态换肤,样式是从一固定的。按照 antd-mobile 的方案:
var ThemeContext = React.createContext()
<ThemeProvider value={{你设置的theme}} />
编写组件时外层统一用 Consumer 封装,这样组件内部只需读取 props 传进来的 style 即可,是一种 styleInJS 的方案。
function WithStyle({children}) {
<ThemeContext.Consumer>
{() => children(format 后的 theme)}
</ThemeContext.Consumer>
}
分离式组件设计
比如 <Tabs><TabPane /><TabPane /></Tabs>
Tabs 需要对传入的 children 进行超越多层的控制,推荐做法
function Tabs(props){
const tabs = React.useMemo(
() => (props.children || []).filter(item => item && typeof item === 'object' && 'key' in item),
[items],
);
return (
<TabContext.Provider value={{ tabs, prefixCls }}>...</TabContext.Provider>
)
}