其他分享
首页 > 其他分享> > 使用React Context全局注入用户认证信息

使用React Context全局注入用户认证信息

作者:互联网

继续记录自己学习React的心得

React Context

Context的功能简单地说就是可以将一些数据注入到Context对象中,使其下辖的组件可以随时随地访问这些数据,省去了逐层传递的步骤。

相对于在组件里挖槽(比如{props.children}),使用Context应该更注重随时随地都可能有需求使用这些数据这个目的。

用到的两个核心API:

使用React Context全局注入用户认证信息

内容衔接之前的用户认证模块。首先需要明确为何需要全局注入用户认证信息,其实一个最简单的答案就是:之前的用户认证模块只提供了用户认证的方法,并没有提供存储用户认证信息的功能,而用户认证信息又是一个大部分组件都有可能使用的数据,所以将其注入到Context中是很有意义的。

目前所构建的用户认证模块大致包括下列内容:

// User接口
export interface User {
  id: string;
  name: string;
  email: string;
  title: string;
  organization: string;
  token: string;
}
// 获取token
export const getToken = () => { ... };
// 登录
export const login = (param) => { ... };
// 注册
export const register = (param) => { ... };
// 登出
export const logout = () => { ... };

下面开始构建AuthContext模块:

该模块包括三大内容:Context对象创建、Provider组件构建、useContext Hook调用。
Context对象需要传入用户认证模块所有的必要数据和方法,如下

const AuthContext = React.createContext<
  | {
      user: User | null;
      login: (form: AuthForm) => Promise<void>;
      register: (form: AuthForm) => Promise<void>;
      logout: () => Promise<void>;
    }
  | undefined
>(undefined);
// 更改Context名称
AuthContext.displayName = "AuthContext";

注意login、register、logout返回的都是fetch()
Provider组件构建涉及到用户认证信息初始化、异步请求状态管理。
用户认证信息初始化主要是需要读取token,用以保持用户登录状态,如下

import * as auth from "用户认证模块";

const boostrapUser = async () => {
  let user = null;
  const token = auth.getToken();
  if (token) {
    const data = await fetch(...) // 验证用户身份
    user = data.user;
  }
  return user;
};

请求状态管理主要是将异步请求状态管理和Provider结合,如下

  const {
    data: user,
    error,
    run,
    isIdle,
    isError,
    isLoading,
    setData: setUser,
  } = useAsync<User | null>();

// 重写用户认证模块的几个函数,将其与异步请求管理相结合
  const login = (form: AuthForm) => auth.login(form).then(setUser);
  const register = (form: AuthForm) => auth.register(form).then(setUser);
  const logout = () => auth.logout().then(() => setUser(null));

// Provider初次渲染时先初始化用户认证信息
  useEffect(() => {
    run(boostrapUser());
  }, []);
// isLoading, isIdle, isError可用于呈现Provider组件不同状态
return (
<AuthContext.Provider
children={children}
value={{ user, login, register, logout }} // 传入Context所需的value
/>
);

useContext Hook的便是提供给其他组件访问Provider属性的一个简单方法,用法如下

export const useAuth = () => {
  const context = React.useContext(AuthContext);
  if (!context) { // 必须保证context对象存在
    throw new Error("useAuth必须在AuthProvider中使用");
  }
  return context;
};

AuthProvider用法

举例在login页面的简单用法:

export const LoginScreen = () => {
  const { user, login } = useAuth();
  const { run, isLoading, error } = useAsync();

  const handleSubmit = async (values: {
    username: string;
    password: string;
  }) => {
    await run(login(values)); // 可全局调用login
  };

  return (
    <Form onFinish={handleSubmit}>
      {user ? ( // 全局读取user,且状态都是一致的
          登录成功,用户:{user?.name}
      ) : null}
      ......
      <Form.Item>
        <LongButton loading={isLoading} htmlType={"submit"} type={"primary"}>
          登录
        </LongButton>
      </Form.Item>
    </Form>
  );
};

 

标签:const,用户,认证,React,user,Context,Provider
来源: https://www.cnblogs.com/wananniannian/p/16691788.html