auth-context实现

834 阅读1分钟

- 用途

context 是用于组件中的全局变量,用context.Provider包裹住就好。 那么auth-context就是用于存储用户信息,登录,登出,注册等属性和函数的。

- 获取当前用户信息

const bootstrapUser = async () => {
    let user = null
    // 这里Auth.token其实就是获取localStorage里的item: token
    const token = Auth.getToken()
    if (token) {
        // 这里http是对fetch方法进行封装,可以调用API
        const data = await http("me", { token })
        user = data.user
    }
    return user;
}

- 创建 Context

    // 定义一下AuhForm属性接口
    interface AuthForm {
        username: string
        password: string
        cpassword?: stirng
    }

    // 默认定义为undefined,但是后面的几个属性需要加进去,所以需要加入泛型,里面放入联合类型。
   const AuthContext = React.CreateContext<
   {
       user: User | null,
       login: (form: AuthForm) => promise<void>,
       register: (form: AuthForm) => promise<void>,
       logout: () => promise<void>
   }
   | undefined
   >(undefined)
   
   // 为了让DevTool 可以方便查询
   AuthContext.displayName = 'AuthContext'
    

- 创建 AuthProvider 返回Context.Providerjsx

const AuthProvider = ({ children }: { children: ReactNode }) => {
    // 用到hooks useState,因为默认为空,赋值后为User,所以用联合类型,传到泛型里。 
    const [user, setUser] = useState<User | null>(null)
    
    // 分别定义 login, register, logout这几个函数
    const login = (form: AuthForm) => Auth.login(form).then(setUser)
    const register = (form: AuthForm) => Auth.login(form).then(setUser)
    const logout = () => Auth.logout().then(() => setUser(null))
    
    // 通过token初步尝试获取user
    useEffect(() => {
        bootstrapUser().then(setUser)
    }, [])
    
    // children 表示该标签的子标签
    return (
        <AuthContext.Provider children={children} value={{user, login, register, logout}} />
    )
}

- 创建 useAuth 用来全局使用这几个属性

const useAuth = () => {
    const context = useContext(AuthContext)
    if (! context) {
        throw new Error('useAuth必须在AuthProvider中使用')
    }
    return context
}