- 用途
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.Provider的jsx
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
}