Redux 是 React 中最常用的状态管理工具(状态容器)
文档:
React的问题:
背景介绍:
为什么需要Redux?
为了让代码各部分职责清晰、明确,Redux 代码被分为三个核心概念:action/reducer/store
action
就是一个对象,type
描述行为,约定payload
做为传参。
解释:
action
行动(名词)、动作action
特点:
action
只描述做什么事情action
是一个JS对象,必须带有 type
属性,用于区分动作的类型payload
有效载荷),配合该动作来完成相应功能举例:
// 计数器案例
{ type: 'increment' } // +1
{ type: 'decrement' } // -1
// 累加10操作
{ type: 'increment', payload: 10 } // +10
{ type: 'decrement', payload: 10 } // -10
// 购物车案例
{ type: 'getGoodsList' }
{ type: 'changeGoodsState', payload: { id: 1, goodsState: true } }
使用函数创建 action 对象,简化多次使用 action 时,重复创建 action 对象
举例:
// 1. 不使用 Action Creator
// 创建多个 action 时,需要重复手动创建 action 对象,很繁琐
{ type: 'decrement', payload: 2 }
{ type: 'decrement', payload: 8 }
// 2. 使用 Action Creator
const decrement = payload => {
return { type: 'decrement', payload }
}
decrement(2) // => { type: 'decrement', payload: 2 }
decrement(8) // => { type: 'decrement', payload: 8 }
// 可以动态创建action
reduce
这个方法reduce
方法,可以来实现累计(比如,累加或者累减)作用:
状态更新
的地方(prevState, action) => newState
原则:
// 伪代码:
// prevState 上一次的状态
// action 当前要执行的动作
const reducer = (prevState, action) => {
return newState
}
示例:
// 示例:
// state 上一次的状态
// action 当前要执行的动作
const reducer = (state, action) => {
switch (action.type) {
// 计数器增加
case 'increment':
// 返回新状态
// return state + 1
// 根据 action 中提供的 payload 来决定到底增加多少
return state + action.payload
// 注意:一定要有 default,如果将来 reducer 无法处理某个 action,就直接将上一次的状态返回即可
default:
return state
}
}
// 模拟调用
reducer(0, { type: 'increment' }) // 本次执行完成后,状态变为:1
reducer(1, { type: 'increment' }) // 本次执行完成后,状态变为:2
reducer(1, { type: 'decrement' }) // 无法处理该 action,所以返回上一次状态:1
总结:
reducer
是修改状态的地方,这里根据action的类型去修改状态通过store关联action和reducer
store:仓库,Redux 的核心,整合 action 和 reducer
store.getState()
store.dispatch(action)
const store = createStore(reducer)
const unSubscribe = store.subscribe(() => {})
unSubscribe()
核心代码:
// 提前安装 redux
import { legacy_createStore as createStore } from 'redux'
// 创建 store
// 参数为:reducer 函数
const store = createStore(reducer)
// 更新状态
// dispatch 派遣,派出。表示:分发一个 action,也就是发起状态更新
store.dispatch(action)
store.dispatch( increment(2) )
// 获取状态
const state = store.getState()
// ---
// 其他 API
// 监听状态变化
const unSubscribe = store.subscribe(() => {
// 状态改变时,执行相应操作
// 比如,记录 redux 状态
console.log(store.getState())
})
// 取消监听状态变化
unSubscribe()
reducer(undefined, {type: "@@redux/INITv.a.4.t.t.p"})
state = 10
10
store.getState()
方法来获取 Redux 状态值就是默认值// 导入 createStore
import { legacy_createStore as createStore } from 'redux'
// 创建 store
const store = createStore(reducer)
// action => { type: 'increment' }
function reducer(state = 10, action) {
console.log('reducer:', state, action)
switch (action.type) {
case 'increment':
return state + 1
default:
return state
}
}
store.dispatch(increment())
// 相当于:store.dispatch({ type: 'increment' })
console.log('store 状态值为:', store.getState())
store.dispatch(action)
更新状态10
)和 action({ type: 'increment' }
),计算出新的状态并返回import { legacy_createStore as createStore } from 'redux'
const store = createStore(reducer)
// reducer(10, { type: 'increment' })
function reducer(state = 10, action) {
console.log('reducer:', state, action)
switch (action.type) {
case 'increment':
return state + 1
default:
return state
}
}
console.log('状态值为:', store.getState()) // 10
// 发起更新状态:
// 参数: action 对象
store.dispatch({ type: 'increment' })
// 相当于: reducer(10, { type: 'increment' })
console.log('更新后:', store.getState()) // 11
纯函数:
// 纯函数:
const add = () => {
return 123
}
add() // 123
add() // 123
const add = (num1, num2) => {
return num1 + num2
}
add(1, 2) // 3
add(1, 2) // 3
const add = (obj) => {
return obj
}
add({ name: 'jack' }) // { name: 'jack' }
add({ name: 'jack' }) // { name: 'jack' }
// 不是纯函数:
const add = () => {
return Math.random()
}
add() // 0.12311293827497123
add() // 0.82239841238741814
JS副作用:
// 无副作用
const add = (num1, num2) => {
return num1 + num2
}
add(1, 3)
// 有副作用:
let c = 0
const add = (num1, num2) => {
// 函数外部的环境产生了影响,所以是有副作用的
c = 1
return num1 + num2
}
add(1, 3)
// 有副作用
const add = (obj) => {
// 因为直接修改了参数的值,对外部的数据产生了影响
obj.num = 123
return obj
}
const o = {}
add(o)
console.log(o) // { num: 123 }
!评论内容需包含中文