三、Redux简介及其主要组成
1,简介
Redux应用需要遵循三大原则,否则程序很容易出现难以察觉的问题。
①唯一数据源
Redux只维护一个全局的状态对象,存储在Redux的store中。唯一数据源是一种集中式管理应用状态的方式,便于监控任意时刻应用的状态和调试应用,减少出错的可能性。
②保持应用状态只读
在任何时候都不能直接修改应用状态。当需要修改应用状态时,必须发送一个action,由这个action描述如何修改应用状态。
③应用状态的改变通过纯函数完成
action表明修改应用状态的意图,真正对应用状态做修改的是reducer。reducer必须是纯函数,所以reducer在接收到action时,不能直接修改原来的状态对象,而是要创建一个新的状态对象返回。
纯函数指的是:
- 对于同样的参数值,函数的返回结果总是相同的。
- 函数的执行不会产生副作用,例如修改外部对象或输出到I/O设备。
2,主要组成
①action:是Redux中信息的载体,是store唯一的信息来源。把action发送给store必须通过store的dispatch方法。action是普通的JavaScript对象,但每一个action必须有一个type属性描述action的类型,type一般为字符串常量。除了type属性外,action的结构完全由自己决定。一般通过action creator创建action,action creator是返回action的函数:
export const ADD_TODO = 'ADD_TODO' export const TOGGLE_TODO = 'TOGGLE_TODO' export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER' // 筛选待办事项列表的条件 export const VisibilityFilters = { SHOW_ALL: 'SHOW_ALL', SHOW_COMPLETED: 'SHOW_COMPLETED', SHOW_ACTIVE: 'SHOW_ACTIVE' } //action creators //新增待办事项 export function addTodo(text) { return { type: ADD_TODO, text } } //修改待办事项的状态,index是待办事项在todos数组中的位置索引 export function toggleTodo(index) { return { type: TOGGLE_TODO, index } } //筛选当前显示的待办事项列表 export function setVisibilityFilter(filter) { return { type: SET_VISIBILITY_FILTER, filter } }
②reducer:action用于描述应用发生了什么操作,reducer则根据action做出相应,决定如何修改应用的状态state。既然是修改state,那么就应该在编写reducer之前设计好state。state既可以包含服务器端获取的数据,也可以包含UI状态:
{ todos: [{ text: 'Learn React', completed: true },{ text: 'Learn React', completed: false }], visibilityFilter: 'SHOW_COMPLETED' }
创建reducer:
import { VisibilityFilters } from './actions' const initialState = { todos: [], visibilityFilter: VisibilityFilters.SHOW_ALL } //reducer function todoApp(state = initialState, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return { ...state, visibilityFilter: action.filter } // 新增待办事项 case ADD_TODO: // 使用了ES6的扩展语法 return { ...state, todos: [ ...state.todos, { text: action.text, completed: false } ] } // 修改待办事项的状态(已完成/未完成) case TOGGLE_TODO: return { ...state, todos: state.todos.map((todo, index) => { if (index === action.index) { return { ...todo, completed: !todo.completed } } return todo }) } default: return state } }
当应用变得复杂时,这个reducer也会逐渐变复杂,这时,一般会拆分出多个reducer,每个reducer处理state中的部分状态:
todos.js:
const todos = (state = [], action) => { switch (action.type) { case 'ADD_TODO': return [ ...state, { id: action.id, text: action.text, completed: false } ] case 'TOGGLE_TODO': return state.map(todo => (todo.id === action.id) ? {...todo, completed: !todo.completed} : todo ) default: return state } } export default todos
visibilityFilter.js:
const visibilityFilter = (state = 'SHOW_ALL', action) => { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } export default visibilityFilter
todoApp.js:
import todos from './todos' import visibilityFilter from './visibilityFilter' const todoApp = combineReducers({ todos, visibilityFilter }) export default todoApp
每个拆分的reducer只接收它负责的state中的部分属性。Redux还提供了一个combineReducers函数,用于合并多个reducer。
还可以为combineReducers接受的参数对象指定和reducer的函数名不同的key值:
可见,combineReducers传递给每个reducer的state中的属性取决于它的参数对象和key值。
③store
store是Redux中的一个对象,也是action和reducer之间的桥梁。store主要负责以下几个工作:
- 保存应用状态
- 通过方法getState()访问应用状态
- 通过方法dispatch(action)发送更新状态的意图
- 通过方法subscribe(listener)注册监听函数、监听应用状态的改变
一个Redux应用中只有一个store,store保存了唯一数据源。store通过createStore()函数创建,创建时需要传递reducer作为参数,创建todos应用的store代码如下:
import { createStore } from 'redux' import todoApp from './reducers' const store = createStore(todoApp)
创建store时还可以设置应用的初始状态:
const store = createStore(todoApp,initialState)
store创建完成后,就可以通过getState()获取当前应用的状态state:
const store = store.getState()
当需要修改state时,通过store的dispatch()方法发送action。例如,发送一个新增待办事项的action:
function addTodo(text) { return {type: 'ADD_TOTO',text} } store.dispatch(addTodo('Learn about actions'))
当todoApp这个reducer处理完成addTodo这个action时,应用的状态会被更新,此时通过store.getState()可以得到最新的应用状态。为了能准确知道应用状态更新的时间,需要向store注册一个监听函数:
let unsubscribe = store.subscribe(() => {
console.log(store.getState())
})
这样每当应用状态更新时,最新的应用状态就会被打印出来。当需要取消监听时,直接调用store.subscribe返回的函数即可:
unsubscribe();
总结:
- 调用store.dispatch(action)。一个action是一个用于描述“发生了什么”的对象。store.dispatch(action)可以在应用的任何地方调用,包括组件、XHR回调,甚至在定时器中。
- Redux的store调用reducer函数。store传递两个参数给reducer:当前应用的状态和action。reducer必须是一个纯函数,它的唯一职责是计算下一个应用的状态。
- 根reducer会把多个子reducer的返回结果组合成最终的状态。跟reducer的构建形式完全取决于用户。Redux提供了combineReducers,方便把多个拆分的子reducer组合到一起。
- Redux的store保存根reducer返回的完整应用状态。此时,应用状态才完成更新。如果UI需要根据应用状态进行更新,那么这就是更新UI的时机。对于React而言,可以在此时调用组件的setState方法,根据新的应用状态更新UI。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通