day-087-eighty-seven-20230607-react项目-知乎日报
react项目-知乎日报
组件销毁
-
每一次组件间销毁的时候:
- 会销毁一些东西:
- 销毁 虚拟DOM和真实DOM
- 销毁 合成事件
- …
- 但有些东西
- 自己设置的定时器、监听器、基于addEventListener进行的事件绑定 … 不会被销毁,需要我们自己手动销毁,来优化内存。
- 会销毁一些东西:
-
对于某些需求下,从A组件跳转到B组件,是不能把A销毁的!我们可以把A隐藏(或者说把A的真实DOM/虚拟DOM缓存起来(可以从页面中移除)),然后在渲染B组件;
- 但是从B组件回到A组件,需要从缓存中把A的内容获取到,渲染到浏览器中!
keep-alive组件
的缓存。- 在React中实现出类似于
keep-alive组件的缓存
效果。
- 在React中实现出类似于
- 但是从B组件回到A组件,需要从缓存中把A的内容获取到,渲染到浏览器中!
react组件缓存机制
- 在React中实现出类似于
keep-alive组件的缓存
效果,有很多方案:-
真正的模拟Vue中的
<keep-alive>
,基于缓存机制,实现相应的效果!- 这种方案比较复杂,我们可以使用别人写好的插件来处理!!
-
需要缓存的组件,我们只是控制其display:none/block
-
不缓存组件,只缓存数据
-
…
-
对UI组件库的二次封装
- 对现在样式围绕功能进行封装和处理。
登录注册组件
-
对于表单组件。
-
表单校验方案:
- 内置校验机制。
- 拿到表单实例,使用实例的函数属性进行校验。
-
发送验证码的机制流程
-
提交表单数据的机制流程
给React设置全局属性
- 原理是因为全局中React是一个对象,在模块中导入时是导入一个引用。引用上的东西都是同一个。
button按钮的loading功能的二次封装
- fang/知乎日报/zhihu/src/components/ButtonAgain.jsx
import { useState } from "react";
import { Button } from "antd-mobile";
import _ from "@/assets/utils";//这个是一个工具库,用的一个each方法是用来对对象进行遍历的。
export default function ButtonAgain(props) {
// 定义状态。
let { children, onClick: handle } = props;
let [loading, setLoading] = useState(false);
// 把除了特定属性之外的其它属性,放在attrs中,最后统一给组件库中的Button。
let attrs = {};
_.each(props, (value, key) => {
if (key === "loading" || key === "children" || key === "onClick") {
return;
}
attrs[key] = value;
});
return (
<Button
{...attrs}
loading={loading}
onClick={async (ev) => {
if (typeof handle !== "function") {
return;
}
setLoading(true);
await handle(ev);
setLoading(false);
}}
>
{children}
</Button>
);
}
个人中心页
- 进入需要用户的页面的流程
用户登录态的动态校验
- 流程说明:
-
在用户登录成功后,服务器会返回一个token。前端把这个token存储进浏览器的localStorage进行存储。
try { console.log(`values`, values); let { phone, code } = values; let { code: resultCode, token } = await API.userLogin(phone, code); // console.log(resultCode, token); if (+resultCode === 0) { // 登录成功:存储Token、获取登录者信息到redux中、提示、跳转。 _.storage.set("TK", token); // localStorage.setItem("TK",65) await queryLoginInfo() message.success(`登录/注册成功`); navigate("/"); } else { message.error(`登录/注册失败`); // Toast.show({ // icon: "fail", // content: "登录/注册失败", // }); // formIns.resetFields(["code"]); formIns.setFieldValue("code", ""); } } catch (error) { console.log("error", error); }
-
在axios实例对象的请求拦截器中,对于部分接口请求或所有请求,都把本地存储的token带到请求头上。
- 这个自定义请求头一般叫authorization。不过具体是什么看接口要求。
// 请求拦截器:在发送请求之前做的事情。例如:传递token。 const apiList = [ `/user_info`, `/upload`, `/user_update`, `/store`, `/store_remove`, `/store_list`,];//需要带上Token信息的接口请求列表,这个列表一般得后端提供。 http.interceptors.request.use((config) => { // 对于部分接口请求,需要把本地存储的Token信息,基于请求头authorization传递给服务器。 let token = _.storage.get("TK"); if (token && apiList.includes(config.url)) { // 也可以不只部分接口,而是对所有接口都直接带上token。 config.headers["authorization"] = token; } return config; });
-
个人中心里的东西,一般放在全局状态中。