2025-05-17 日报 Day189

2025-05-17 日报 Day189

Yuyang 前端小白🥬

今日的鸡汤

平凡铸就伟大,英雄来自人民。每一份伟大的成就,无不立足于平凡的岗位和工作;每一段不凡的人生,无不依托于平凡的日积月累。

今日学习内容

1、https://www.youtube.com/watch?v=EVFZazcxAbo&t=4112s

今日笔记

Redux背后的架构思想-认识Flux架构
Redux的核心思想是“单向数据流”,它的设计灵感来源于Flux架构。

View(视图层):
用户界面该用户界面可以是以任何形式实现出来的,Flux架构与React之前并不存在耦合关系
Action(动作):
视图层发出的消息触发应用的改变
Dispatcher(派发器):
负责对action进行分发
Store(数据层):
存储应用状态的”仓库”

image-20250709085526692

Redux关键要素与工作流回顾:
Store:它是一个单一的数据源,而且是只读的
Action:是“动作”的意思,它是对变化的描述
Reducer:它负责对变化进行分发和处理,最终将你的数据返回给Store

![image-20250709224602564](../../../../../Library/Application Support/typora-user-images/image-20250709224602564.png)

Redux文件:

  • utils
  • applyMiddleware.js
  • bindActionCreators.js
  • combineReducers.js
  • compose.js
  • createStore.js
  • index.js
1
2
3
4
5
6
7
8
// 引入redux
import { createStore } from 'redux'
// 创建store
const store = createStore(
reducer,
initial_state,
applyMiddleware(middleware1, middleware2, ....)
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
function createStore(reducer, preloadedState, enhancer){
// 这里处理的是没有设定初始状态的情况,也就是第一个参数和第二个参数都传function的情况
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
// 此时第二个参数会被认为是enhancer(中间件)
enhancer = preloadedState;
preloadedState = undefined;
}

// 当enhancer不为空时,便会将原来的createStore作为参数传入到enhancer中
if (typeof enhancer !== 'undefined') {
return enhancer(createStore)(reducer, preloadedState);
}

// 记录当前的reducer,因为replaceReducer会修改reducer的内容
let currentReducer = reducer;
// 记录当前的state
let currentState = preloadedState;
// 声明listeners数组,这个数组用于记录在subscribe中订阅的事件
let currentListeners = [];
// nextListeners是currentListener的快照
let nextListeners = currentListeners;
// 该变量用于记录当前是否正在进行dispatch
let isDispatching = false;

// 该方法用于确认快照是currentListeners的副本,而不是currentListeners本身
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice();
}
}

// 我们通过调用getState来获取当前的状态
function getState() {
return currentState;
}

// subscribe订阅方法,它将会定义dispatch最后执行的listeners数组的内容
function subscribe(listener){
// 校验listener的类型
if(typeof listener !== 'function') {
throw new Error('Listener must be a function');
}
// 禁止在reducer中调用subscribe
if(isDispatching) {
throw new Error('You may not call store.subscribe() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of subscribing.');
}

// 该变量用于防止调用多次unsubscribe函数
let isSubscribed = true;
// 确保nextListeners是currentListeners的副本
ensureCanMutateNextListeners();
// 注册监听函数
nextListeners.push(listener);

// 返回取消订阅当前listener的方法
return function unsubscribe(){
if(!isSubscribed) {
return;
}
isSubscribed = false;
ensureCanMutateNextListeners();
const index = nextListeners.indexOf(listener);
// 将当前的listener从nextListeners数组中删除
nextListeners.splice(index, 1);
}
}

// 定义dispatch方法,用于派发action
function dispatch(action) {
// 校验action的类型
if(!isPlainObject(action)) {
throw new Error('Actions must be plain objects. Use custom middleware for async actions.');
}

// 约束action中必须有type属性作为action的唯一标识
if(typeof action.type === 'undefined') {
throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');
}

// 若当前已经位于dispatch的流程中,则不允许再度发起dispatch(禁止套娃)
if(isDispatching) {
throw new Error('Reducers may not dispatch actions.');
}

try{
// 执行reducer前,先“上锁”,标记当前已经存在dispatch执行流程
isDispatching = true;
// 执行reducer,获取新的state
currentState = currentReducer(currentState, action);
}finally{
// 执行结束后,把“锁”打开,允许再次进行dispatch
isDispatching = false;
}

// 触发订阅
const listeners = currentListeners = nextListeners;
for(let i = 0; i < listeners.length; i++){
const listener = listeners[i];
listener();
}
return action;
}

// replaceReducer可以更改当前的reducer
function replaceReducer(nextReducer) {
currentReducer = nextReducer;
dispatch({ type: ActionTypes.REPLACE });
return store;
}

// 初始化state,当派发一个type为ActionTypes.INIT的action时,reducer会返回初始状态
dispatch({ type: ActionTypes.INIT });

// observable方法可以忽略,它在redux内部使用,开发者一般不会直接接触
function observable() {
// observable方法的实现
}

return {
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
}

image-20250710001052929

image-20250710001151896

此页目录
2025-05-17 日报 Day189