1 hook(useXXXX),无论是自定义,还是基础内置的,都不完整,抽象通用的R 组件;用来给其它R组件添加功能;
2 RV组件 只是R组件中的一种,R组件封装了浏览器行为的JS对象,可用JSX表达2021-08-22
问题:实现前端 UA 模块
解题思路:
1 在全局创建一个身份认证对象(auth),光认证数据(user)不够,因为还有登录等逻辑
2 通过Context API将 auth放入全局根节点,那样节点树下的所有节点可以访问auth的API
L 主要是 login(logout)页,和私有页面 使用
3 相关页面使用这个context( 使用useContext hook) ,并调用需的auth API
L login页面使用 auth.login
E private page 使用 auth.user
L 怎么定义private page?private M(private API)
hook: 自定义hook制作 是用来 给一些RV组件添加额外(但通用)的形式功能
UA: 1) user的(credantial)创建,2) 登录认证,和3) 资源访问验证是可以分开 的
router: 给 RV组件 添加导航和加载逻辑(通过一个route状态)
UA 实现的模块组成
1 App.js | @1 UA模块的根基,全局数据
2 private page( 例如 Navbar.js)| @2 3) 资源访问验证
3 login.js | @3 2) 登录认证
4 use-auth.js | 这是最主要的自定义hook 实现
4 use-auth.js | 这是最主要的自定义hook 实现
// use-auth.js是一个混合模块,把「相关但独立的」代码 写在一个js模块里
import React, { useState, useEffect, useContext, createContext } from "react";
// 这个全局context
const authContext = createContext();
// 这个是模块API,输出 context ,用于@2 @3
export const useAuth = () => {
return useContext(authContext);
};
// 这个是 挂接 auth对象的 API,用于 @1
// 本身也是一个RV组件(可用于JSX上),并且接受一个子组件参数
export function ProvideAuth({ children }) {
const auth = useProvideAuth();
}
// 1 这是一个hook , 并且有 状态(useState) 和 效应(useEffect)
// 2 这个没有export出去,不是API,只是内部模块使用
// 3 被节点顶层 data provider RV组件(ProvideAuth) 唯一的“勾选”功能
function useProvideAuth() {
const [user, setUser] = useState(null);
const signin = (email, password) => {};
const signup = (email, password) => {};
const signout = () => {};
const sendPasswordResetEmail = (email) => {};
const confirmPasswordReset = (code, password) => { };
useEffect(() => {}, []);
// Return the user object and auth methods
return {
user, signin, signup, signout, sendPasswordResetEmail, confirmPasswordReset,
};
}
读代码之外
读代码之外,我们应该具备怎么样的能力迁移
1 将相关(亲缘性大)但应该有一定独立性的代码(函数,全局数据,类对象)写同一个js文件模块中
2 使用React Context API,解决全局状态 协作的任务(此实例是 认证的状态,和认证的逻辑)
L data provider 模式
3 使用自定义hook,制作 通用的RV组件
L hook就是不完整,不具体的RV组件,别忘记
E 此实例,useProvideAuth,useAuth 都是自定义hook,都是无V的RV组件(通用部分),用来 为某RV组件添加功能
L useProvideAuth 给provider节点 勾选 auth对象
L data provider 模式,是实现context 全局状态的设计模式
E useAuth 给private page 勾选 authContext
4 使用 children prop制作 父子关系的RVX组件
此里,第3条自定义hook的知识迁移最难,也最有价值
最难的原因是,对RV组件的什么东西,应该,可以抽取出来,缺乏知识
L 例如,你不太容易理解,data provider的那个顶层对象(ProvideAuth),居然也是一个RV组件
L 理由是,第一,它勾选了useProvideAuth的功能,并且返回JSX
E 如果将用VDOM输出的定为RV组件,那 ProvideAuth是没有自己(子组件不算,它就是一个模板)VDOM输出的 R组件;可用JSX表达
L R组件 是有浏览器行为的 JS对象;有DOM输出行为的R组件中最常用的一种