Lesson 34 动手实现 Redux(五):不要问为什么的 reducer
发布日期:2022-09-10 03:03:39 浏览次数:3 分类:技术文章

本文共 3846 字,大约阅读时间需要 12 分钟。

Lesson 34 动手实现 Redux(五):不要问为什么的 reducer

经过了这么多节的优化,我们有了一个很通用的 createStore

function createStore (state, stateChanger) {
const listeners = [] const subscribe = (listener) => listeners.push(listener) const getState = () => state const dispatch = (action) => {
state = stateChanger(state, action) // 覆盖原对象 listeners.forEach((listener) => listener()) } return {
getState, dispatch, subscribe }}

它的使用方式是:

let appState = {
title: {
text: 'React.js 小书', color: 'red', }, content: {
text: 'React.js 小书内容', color: 'blue' }}function stateChanger (state, action) {
switch (action.type) {
case 'UPDATE_TITLE_TEXT': return {
...state, title: {
...state.title, text: action.text } } case 'UPDATE_TITLE_COLOR': return {
...state, title: {
...state.title, color: action.color } } default: return state }}const store = createStore(appState, stateChanger)...

我们再优化一下,其实 appStatestateChanger 可以合并到一起去:

function stateChanger (state, action) {
if (!state) {
return {
title: {
text: 'React.js 小书', color: 'red', }, content: {
text: 'React.js 小书内容', color: 'blue' } } } switch (action.type) {
case 'UPDATE_TITLE_TEXT': return {
...state, title: {
...state.title, text: action.text } } case 'UPDATE_TITLE_COLOR': return {
...state, title: {
...state.title, color: action.color } } default: return state }}

stateChanger 现在既充当了获取初始化数据的功能,也充当了生成更新数据的功能。如果有传入 state 就生成更新数据,否则就是初始化数据。这样我们可以优化 createStore 成一个参数,因为 statestateChanger 合并到一起了:

function createStore (stateChanger) {
let state = null const listeners = [] const subscribe = (listener) => listeners.push(listener) const getState = () => state const dispatch = (action) => {
state = stateChanger(state, action) listeners.forEach((listener) => listener()) } dispatch({
}) // 初始化 state return {
getState, dispatch, subscribe }}

createStore 内部的 state 不再通过参数传入,而是一个局部变量 let state = nullcreateStore 的最后会手动调用一次 dispatch({})dispatch 内部会调用 stateChanger,这时候的 statenull,所以这次的 dispatch 其实就是初始化数据了。createStore 内部第一次的 dispatch 导致 state 初始化完成,后续外部的 dispatch 就是修改数据的行为了。

我们给 stateChanger 这个玩意起一个通用的名字:reducer,不要问为什么,它就是个名字而已,修改 createStore 的参数名字:

function createStore (reducer) {
let state = null const listeners = [] const subscribe = (listener) => listeners.push(listener) const getState = () => state const dispatch = (action) => {
state = reducer(state, action) listeners.forEach((listener) => listener()) } dispatch({
}) // 初始化 state return {
getState, dispatch, subscribe }}

这是一个最终形态的 createStore,它接受的参数叫 reducerreducer 是一个函数,细心的朋友会发现,它其实是一个纯函数(Pure Function)。

reducer

createStore 接受一个叫 reducer 的函数作为参数,这个函数规定是一个纯函数,它接受两个参数,一个是 state,一个是 action

如果没有传入 state 或者 statenull,那么它就会返回一个初始化的数据。如果有传入 state 的话,就会根据 action 来“修改“数据,但其实它没有、也规定不能修改 state,而是要通过上节所说的把修改路径的对象都复制一遍,然后产生一个新的对象返回。如果它不能识别你的 action,它就不会产生新的数据,而是(在 default 内部)把 state 原封不动地返回。

reducer 是不允许有副作用的。你不能在里面操作 DOM,也不能发 Ajax 请求,更不能直接修改 state,它要做的仅仅是 —— 初始化和计算新的 state

现在我们可以用这个 createStore 来构建不同的 store 了,只要给它传入符合上述的定义的 reducer 即可:

function themeReducer (state, action) {
if (!state) return {
themeName: 'Red Theme', themeColor: 'red' } switch (action.type) {
case 'UPATE_THEME_NAME': return {
...state, themeName: action.themeName } case 'UPATE_THEME_COLOR': return {
...state, themeColor: action.themeColor } default: return state }}const store = createStore(themeReducer)...

当前内容版权归 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请点击 .

最初的起点:

上一篇:

下一篇:

转载地址:https://blog.csdn.net/Mr_zzr/article/details/125797428 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Lesson 35 动手实现 Redux(六):Redux 总结
下一篇:Lesson 33 动手实现 Redux(四):共享结构的对象提高性能

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月20日 15时29分28秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

向mysql数据库中添加批量数据类型_使用JDBC在MySQL数据库中快速批量插入数据 2019-04-21
最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐! 2019-04-21
mssql连接mysql数据库文件_在本地 怎么远程连接MSSQL数据库 2019-04-21
mssql 远程无法连接mysql_解决SQLServer远程连接失败的问题 2019-04-21
linux mysql c++编程_Linux下进行MYSQL的C++编程起步手记 2019-04-21
Maria数据库怎么复制到mysql_MySQL、MariaDB数据库的AB复制配置过程 2019-04-21
mysql5.6 icp mrr bak_【mysql】关于ICP、MRR、BKA等特性 2019-04-21
mysql utf8跟utf8mb4_MySQL utf8 和 utf8mb4 的区别 2019-04-21
docker mysql开机自启动_Docker学习4-学会如何让容器开机自启服务【坑】 2019-04-21
在mysql中删除表正确的是什么_在MySQL中删除表的操作教程 2019-04-21
mysql有3个共同好友_共同好友mysql 2019-04-21
代理查询 mysql_查询数据库代理设置 2019-04-21
mysql dif_mysqldiff实现MySQL数据表比较 2019-04-21
mysql 允许其他主机访问权限_允许其他主机访问本机MySQL 2019-04-21
druid不能close mysql连接_alibaba druid mysql连接问题 2019-04-21
mysql 设置按天分表_MySQL 优化实战记录 2019-04-21
java连接mysql 不推荐_java连接mysql 2019-04-21
mysql数据库 quota_shell脚本抓取用户存储quota写道mysql并展现到grafana面板 2019-04-21
idea测试连接mysql报错08001_IDEA连接MySQL错误 2019-04-21
layui导入模板数据_layui表格-template模板的三种用法 2019-04-21