何时使用
何时使用context是在做这个事情之前需要考虑的
全局状态变量,如用户信息、UI主题这种整个项目组件之间共享的值。也可能是全局可获取的方法,比如用户登录、退出登录等函数方法
如何使用
Context提供了Provider和Consumer两个组件,消费方式也有多种,主要从官网查看,因为项目中往往存在多个Context,所以项目中使用的是Consumer回调函数
配置
// user.tsx
import React from 'react';
import { UserInfo } from '@/models/user';
/** 默认值 */
const defaultValue = {
/** 用户信息 */
user: undefined as (undefined | UserInfo),
/** 登录 */
async login(username: string, password: string) {},
/** 退出登录 */
async logout() {},
/** 是否登录 */
isLogin: false,
};
export const UserContext = React.createContext(defaultValue);
export type UserState = typeof defaultValue;
/**
* @description 用户状态
* @author max
* @date 2022/04/15
* @export
* @class UserProvider
* @extends {React.PureComponent<{}, UserState>}
*/
export default class UserProvider extends React.PureComponent<{}, UserState> {
constructor(props: {}) {
super(props);
this.state = {
...defaultValue, ...{
login: this.login,
logout: this.logout,
},
};
}
/** 登录 */
login = async () => {
console.info('login function');
this.setState({isLogin: true});
await new Promise((r) => r({}));
};
/** 退出登录 */
logout = async () => {
console.info('logout function');
this.setState({
isLogin: false,
});
};
render() {
const { children } = this.props;
return (
<UserContext.Provider value={this.state}>
{children}
</UserContext.Provider>
);
}
}
Provider
// index.tsx
import UserProvider from '@contexts/user';
ReactDOM.render(
<UserProvider>
<App />
</UserProvider>
document.getElementById('root'),
);
Consumer
当使用Context时间,往往不会只有一个,如果一个组件涉及到多个Context消费,就会出现“回调地狱”的情况,所以考虑使用高阶组件的方式进行一层包裹。写一个高阶函数
export function withContext<S>(Context: React.Context<S>) {
return function <P extends S>(Component: React.ComponentType<P>) {
return function(props: Omit<P, keyof S>) {
return <Context.Consumer>{(data: S) => <Component {...{ ...props as any, ...data as any }} />}</Context.Consumer>;
};
};
}
如上,消费Context时,使用下面的方式就可以了
import { withContext } from '@contexts/index';
import { UserContext, UserState } from '@contexts/user';
export default withContext(UserContext)(Demo);
Demo组件就可以访问user这个context提供的数据和函数了