一、Redux
使用Redux相对于context api的优势:
单一数据源:使用全局唯一的状态树来存储应用程序的状态,使得状态管理更加集中和一致。使用Context API时,状态可能会分散在多个上下文中。
分离关注点:通过actions和reducers将状态更新逻辑与组件逻辑分离。使用Context API时,状态更新逻辑可能会与组件逻辑混在一起,导致组件和逻辑之间的耦合度增加。
// actions.js
export const fetchDataRequest = () => ({
type: 'FETCH_DATA_REQUEST'
});
export const fetchDataSuccess = data => ({
type: 'FETCH_DATA_SUCCESS',
payload: data
});
export const fetchData = () => async dispatch => {
dispatch(fetchDataRequest());
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
dispatch(fetchDataSuccess(data));
} catch (error) {
console.error(error);
}
};
// reducer.js
const initialState = {
loading: false,
data: null
};
export const dataReducer = (state = initialState, action) => {
switch (action.type) {
case 'FETCH_DATA_REQUEST':
return { ...state, loading: true };
case 'FETCH_DATA_SUCCESS':
return { ...state, loading: false, data: action.payload };
default:
return state;
}
};
// App.js 和其他 Redux 相关代码保持不变
// DataComponent.js// 组件逻辑中,完全跟状态更新逻辑(异步获取数据等)解耦
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from './actions';
const DataComponent = () => {
const { data, loading } = useSelector(state => state);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchData());
}, [dispatch]);
return (
{loading ? (
Loading...
) : (
Data: {data && JSON.stringify(data)}
)}
);
};
export default DataComponent;
二、Nextjs
分为AppRouter和PageRouter两种模式,其中AppRouter是更新、更为推荐的模式
1、SSR
AppRouter中,默认组件就是Server Component,对应访问请求就是SSR模式; 通过设置`client component`的指令,标记组件是Client Component,对应页面访问就是CSR模式。
PageRouter中,如果页面组件文件有实现类似getServerProps、getIniialProp等方法,就是SSR模式; 反之,就是CSR模式。
2、缓存
AppRouter模式,Next.js里面自动扩展了fetch方法。 会实现Request模式、Data模式等缓存方案。
3、部署
静态资源: build后静态资源在/public/static目录,推送到CDN; 然后在next.config.js里面配置pubilcPath为CDN地址
服务: 部署执行 next start就可以; 或者配置docker file
4、常见坑
SSR页跳转另外SSR页,原页面会因为store更新而多余render
next-redux-wrapper在接收到SSP的返回后,会默认触发Hydrate Action,从而引起不同页面的Reducer监听到 Hydrate Action触发,然后进行Store的更新;而此时Store只有新SSR页的store数据,原SSR页的store数据没有了,所以导致render。
https://segmentfault.com/a/1190000043700244
常见问题
App Router常见问题
三、Fiber原理
1、Fiber是什么?
Fiber是一种新的数据结构,表示一个元素节点,包含了type、props、key、parent、sibling、child等属性。 用一种双向链表结构取代以前的树节点结构。
2、为什么需要Fiber?
因为React每次状态更新,就需要重新构建整个React组件树的Virtual Dom; 这就带来了新旧Virtual Dom对比的CPU压力,从而会占据JS thread运行时间,导致卡顿情况。
引入Fiber:
把1个大rerender过程划分到多个桢里面,虽然整体耗时不变,但用户体感上会更流畅
3、 如何实现Fiber?
Fiber的双向链表结构,保证只要记录上一次中断的Fiber节点,就可以继续往后遍历(通过parent、sibling、child等指针)执行
类似借助浏览器的requestIdleCallback,再每帧空余时间执行(实际上是React为了浏览器兼容,自己实现了Polyfill)
const workLoop = (deadLine) => {
let shouldYield = false;// 是否该让出线程
while(!shouldYield){
console.log('working')
// 遍历节点等工作。。。
shouldYield = deadLine.timeRemaining()<1; // deadLine.timeRemaining是浏览器API,用于返回当前桢还剩余时间
}
requestIdleCallback(workLoop)
}
requestIdleCallback(workLoop);
4、Diff算法
