redux 函数式组件_从Redux学习函数式编程设计

2023-12-21 21:50

本文主要是介绍redux 函数式组件_从Redux学习函数式编程设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

redux 函数式组件

Before I set my eyes on the Redux source code, I naively thought OOP is superior than FP(Functional Programming) as a programming paradigm. But this is not right. As we know that FP is dedicated to forming a easy to understand and clear workflow without those obscure abstracted objects and relations. It’s much closer to human’s procedural mode of thinking.

在着眼于Redux源代码之前,我天真的以为OOP优于FP(功能性编程)作为编程范例。 但这是不对的。 众所周知,FP致力于形成一个易于理解和清晰的工作流,而没有那些晦涩的抽象对象和关系。 它更接近于人类的程序思维方式。

Visit Pitayan.com to read the original article.

访问Pitayan.com以阅读原始文章。

Now React has already got hooks which can handle the "states" properly event without Redux. The demand for Redux could be declining but its code base is still worth learning. Especially for those who wants to enlighten themselves in functional programming. So, I guess it's never a bad idea to learn from a good example even though it is "obsolete" (not at all).

现在, React已经有了钩子,可以在没有Redux的情况下正确处理“状态”事件。 对Redux的需求可能会下降,但是其代码库仍然值得学习。 特别是对于那些希望在函数式编程中有所启发的人。 因此,我想从一个好的例子中学习,即使它已经“过时了”(一点也不没有),这绝不是一个坏主意。

When I started reading the Redux source code, I immediately felt the power of this unfamiliar usage of my familiar programming language. It feels like exploring an acient cave with a torch lighting up the paintings and found the great secret.

当我开始阅读Redux源代码时,我立即感受到了我熟悉的编程语言的这种陌生用法的力量。 感觉就像是用火把照亮一个古老的山洞,照亮了画作,并找到了伟大的秘密。

In order to know more about what Redux benefits from FP, I researched the Reduxsource code and created a mini version of it.

为了更多地了解Redux从FP中获得的好处,我研究了Redux源代码并创建了它的迷你版本。

Never be afraid of reinventing the wheel.

永远不要害怕重新发明轮子。

回顾Redux的工作原理 (Recap How Redux Works)

There are 4 basic key points for Redux:

Redux有4个基本要点:

  1. Create a store for data and let the view subscribe to it

    创建数据存储并让视图订阅
  2. The view dispatches an action to submit the changs

    视图派遣一个动作来提交变更
  3. The reducer changes the state based on the action type

    减速器根据动作类型改变状态
  4. Finally return the new state and triggers the view to change

    最后返回新状态并触发视图更改

This is the classic diagram explaining how Redux works:

这是解释Redux如何工作的经典图表:

Image for post

From the diagram above, it’s easy to find the keywords: actionstorereducerviewsubscribe and dispatch. And the next is to handle the relations among these keywords.

在上图中,很容易找到关键字: actionstorereducerviewsubscribedispatch 。 接下来是处理这些关键字之间的关系。

Redux方法比较:FP与OOP (Redux Approach Comparison: FP vs OOP)

Example usage of Redux

Redux的用法示例

const store = createStore(
combineReducers({
one: oneReducer,
two: twoReducer
}),
applyMiddleware(ReduxThunk, ReduxLogger)
);

Imagine if we do this in OOP, it may look like this:

想象一下,如果我们在OOP中执行此操作,则可能看起来像这样:

(The following is just my imagination. Not how older Redux behaves)

(以下只是我的想象。不是老Redux的行为方式)

const store = new Store();
store.setReducers({
one: oneReducer,
two: twoReducer
});
store.setMiddlewares({
ReduxThunk,
ReduxLogger
});

So, what are the differences? Both are good approaches IMO.

那么,有什么区别呢? 两者都是IMO的好方法。

FP does a good job on combining the functions together without side-effects. The return value is consistent which made the program returnings foreseeable during or after the execution.

FP在将功能组合在一起而没有副作用方面做得很好。 返回值是一致的,这使得在执行期间或执行之后可以预见程序的返回。

OOP made a solid structure which defined all the attributes a data model should contain. It makes it easy to modify or configure the data model.

OOP建立了一个坚实的结构,该结构定义了数据模型应包含的所有属性。 它使修改或配置数据模型变得容易。

In Redux, the reduers and middlewares are usually defined only once. It means, we don't need the ability to update these properties and we don't hope them to be altered during the runtime. As for FP approach, it utilizes the closure technique that kills the possbility of exposing the internal properties. With some fantastic FP techniques (curry, compose, pipe), it's even making the program much more human-readable than OOP.

在Redux中 , reduersmiddlewares通常只定义一次。 这意味着,我们不需要更新这些属性的能力,也不希望在运行时对其进行更改。 至于FP方法,它利用closure技术来消除暴露内部特性的可能性。 借助一些出色的FP技术(curry,compose,pipe),它甚至使程序比OOP更具可读性。

I would say FP should be the best fit for such scenario. Of course, the FP I’m talking about here is far from the real functional programming like Haskell. But at least the idea of utilizing FP techniques in Javascript is something to follow.

我想说FP应该最适合这种情况。 当然,我在这里谈论的FP与真正的函数式编程(例如Haskell)相去甚远。 但是至少可以遵循在Javascript中使用FP技术的想法。

Image for post

出色的Redux FP设计 (Wonderful Redux FP Design)

In Redux, there is no class at all (In the earlier versions, it was once based on Class). All of its core APIs return either value or function (function factory). And this is exactly what FP expects a function to behave:

在Redux中,根本没有类(在早期版本中,它曾经是基于Class )。 其所有核心API均返回值或函数(函数工厂)。 这正是FP希望函数起作用的内容:

Pure with no side effects.

纯净,无副作用。

  • createStore: returns new Object { getState, dispatch, subscribe }

    createStore:返回新Object {getState,dispatch,subscribe}

  • combineReducers: returns new Function

    CombineReducers:返回新Function

  • applyMiddleware: returns new Function

    applyMiddleware:返回新Function

To explain the Redux design in an easy way, I implemented only the very core part of the APIs above. Since the latest version’s core concept hasn’t changed much, I wrote the source code based on very primitive version of Redux v1.0.1. Because I believe the very first related version would be the most comprehensive one to look at.

为了方便地解释Redux设计,我仅实现了上述API的核心部分。 由于最新版本的核心概念没有太大变化,因此我基于非常原始的Redux v1.0.1编写了源代码。 因为我相信第一个相关版本将是最全面的版本。

Let’s have a look.

我们来看一下。

createStore (createStore)

createStore defines those APIs that can be used within components. It's more like setter and getter

createStore定义了可以在组件内使用的那些API。 更像是settergetter

  • getState

    getState
  • dispatch

    调度
  • subscribe

    订阅
export default function createStore (reducer, enhancer) {
if (enhancer) {
return enhancer(createStore)(reducer);
} let currentState;
// Redux now uses a shallow copy `nextListeners` via `ensureCanMutateNextListeners()`
// to prevent bugs in the middle of `dispatch`
let currentListeners = []; function getState () {
return currentState;
} // Register callbacks to execute after changes
function subscribe (listener) {
currentListeners.push(listener); return () => {
// empty listeners
const index = currentListeners.indexOf(listener);
currentListeners.splice(index, 1);
};
} function dispatch (action) {
currentState = reducer(currentState, action);
// state changes, notify to invoke callbacks
currentListeners.forEach(listener => listener());
} // Initialize Redux by calling a virtual reducer
dispatch({ type: "MY-MINI-REDUX" }); return {
getState,
dispatch,
subscribe
};
}

CombineReducers (combineReducers)

Returns a new function that can return the new state. Can’t be any purer.

返回可以返回新状态的新函数。 不能纯洁。

// This is just a helper function to map through the Object
function mapValues(obj, fn) {
return Object.keys(obj).reduce((result, key) => {
result[key] = fn(obj[key], key);
return result;
}, {});
}export default function combineReducers (reducers) {
return function combination (state = {}, action) {
// Official Redux uses `pick` on filtering reducers.
// Let's trust reducers are functions here
return mapValues(reducers, (reducer, key) => reducer(state[key], action))
};
}

applyMiddleware (applyMiddleware)

I personally think the applyMiddleware API is the most amazing part of Redux. It provides an optimal solution to apply 3rd party plugins.

我个人认为applyMiddleware API是Redux最神奇的部分。 它提供了应用第三方插件的最佳解决方案。

The FP compose in the source code is corresponding to Math's associative law in my understanding.

该FP compose的源代码对应于数学的结合律在我的理解。

( x ∗ ( yz ) ) = xyz

( x *( y * z ))= x * y * z

The usage of applyMiddleware is actually a form of a pipe that allows us to inject enhancement functions that returns the store Object. It's pretty similar to Aspect Oriented Programming which the most typical example is the annotation / decorator.

applyMiddleware的用法实际上是pipe一种形式,它使我们可以注入增强功能以​​返回存储对象。 它与Aspect Oriented Programming非常相似,后者最典型的示例是注释/装饰器。

// Combine the functions
// a(b(c())) => compose(a, b, c)
function compose(...funcs) {
return funcs.reduceRight((composed, f) => f(composed));
}export default function applyMiddleware(...middlewares) {
return next => (reducer, initialState) => {
const store = next(reducer, initialState);
let dispatch = store.dispatch;
const middlewareAPI = {
getState: store.getState,
dispatch: action => dispatch(action)
};
const chain = middlewares.map(middleware => middleware(middlewareAPI)); // Enhance the `dispatchers` by applying middlewares to each of them
dispatch = compose(...chain, store.dispatch); return {
...store,
dispatch
};
};
}

Redux中间件 (Redux Middlewares)

There are some famous middlewares for Redux like redux-thunk and [redux-logger(https://github.com/LogRocket/redux-logger). These are the good examples using applyMiddleware API to enhance the functionalities. Furthermore, their code base is astonishingly small. The core part has only a few lines of code.

Redux有一些著名的中间件,例如redux-thunk和[redux-logger( https://github.com/LogRocket/redux-logger )。 这些是使用applyMiddleware API增强功能的好例子。 此外,它们的代码库非常小。 核心部分只有几行代码。

All of the middlewares are curry functions.

所有的中间件都是curry函数。

funcA => funcB => funcC

funcA => funcB => funcC

funcB = funcA()

funcB = funcA()

funcC = funcB()

funcC = funcB()

This is extremly helpful when I need other contexts to use within the code block. As of the examples, it’s easy to find that next and action are passed in as context to help handle some complex cases.

当我需要在代码块中使用其他上下文时,这非常有用。 在示例中,很容易发现将nextaction作为上下文传递来帮助处理一些复杂的情况。

Redux Thunk (Redux Thunk)

redux-thunk allows to use function as dispatch parameter so that I could do something right before "dispatching".

redux-thunk允许使用函数作为dispatch参数,这样我就可以在“调度”之前做一些事情。

// without redux-thunk
dispatch({ type: 'action', payload: 'value' })// with redux-thunk
// the dispatch is wrapped up by a new function
dispatch(function (dispatch, getState) {
console.log('redux-thunk')
dispatch({ type: 'action', payload: 'value' })
})

Here is the core:

这是核心:

// Allow passing function to dispatch
export default function thunk({ dispatch, getState }) {
return next => action => {
if (typeof action === "function") {
return action(dispatch, getState);
} return next(action);
};
}

Redux记录器 (Redux Logger)

It’s easy to guess what this middleware does. It simply outputs the state changes.

很容易猜出该中间件的功能。 它仅输出状态更改。

// Output the previous and current state in console
export default function logger({ getState }) {
return next => action => {
console.log("======== Redux Logger ========");
console.log("Action Type: ", action.type);
const prevState = getState();
console.log("Prev: ", prevState); const returnValue = next(action); const nextState = getState();
console.log("Next: ", nextState);
console.log("==============================");
return returnValue;
};
}

演示应用 (A demo app)

I implemented mini version of redux and a small counter application to demostrate the functions. The application will do four arithmetic operations: plus, minus, multiply and divide. The number will change after clicking the operation button. Meanwhile, multiply and divide will have 300ms' delay which is enabled by a custom middleware (a mini redux-thunk).

我实现了Redux的迷你版和一个小型计数器应用程序以演示这些功能。 该应用程序将执行四个算术运算:加,减,乘和除。 单击操作按钮后,数字将更改。 同时, multiplydivide将具有300ms的延迟,这是通过自定义中间件(小型redux-thunk)启用的。

Repository link of “mini-redux”:

“ mini-redux”的存储库链接:

https://github.com/daiyanze/mini-redux

https://github.com/daiyanze/mini-redux

Demo App link:

演示应用链接:

https://daiyanze.com/mini-redux/build/index.html

https://daiyanze.com/mini-redux/build/index.html

Image for post

The app has one child component: MiniReduxComp. In my mini-redux, I didn't create a context provider to trigger updates. Instead, I subscribe to the store changes within the component and do forceUpdate to react to changes.

该应用程序具有一个子组件: MiniReduxComp 。 在我的迷你Redux中,我没有创建上下文提供程序来触发更新。 相反,我订阅了组件内的存储更改,并执行forceUpdate对更改做出React。

I also applied the custom middlewares redux-thunk and redux-logger to enrich the functions.

我还应用了定制的中间件redux-thunkredux-logger以丰富功能。

import React, { Component } from 'react';
import store from '../store'export default class MiniReduxComp extends Component { componentDidMount() {
this.unsubscribe = store.subscribe(() => this.forceUpdate());
} componentWillUnmount() {
this.unsubscribe && this.unsubscribe();
} plus = () => store.dispatch({ type: "PLUS" }) minus = () => store.dispatch({ type: 'MINUS' }) multiply = () => store.dispatch((dispatch, getState) => {
setTimeout(() => {
dispatch({ type: 'MULTIPLY' })
}, 300)
}) divide = () => store.dispatch((dispatch, getState) => {
setTimeout(() => {
dispatch({ type: 'DIVIDE' })
}, 300)
}) render() {
return (
<div>
<h4>Plus / Minus 1</h4> <p>{store.getState().count}</p> <button onClick={this.plus}>+1</button>
<button onClick={this.minus}>-1</button> <br />
<br /> <h4>Multiply / Divide 2 (0.3s delay)</h4>
<p>{store.getState().double}</p> <button onClick={this.multiply}>x2</button>
<button onClick={this.divide}>/2</button>
</div>
);
}
}

结论 (Conclusion)

I think in modern web development, OOP is still the mainstream. Yet we could see that there are some open source projects mix the programming paradigms and deliver very qualified frameworks (e.g. nest.js). Thanks to React communities, FP is part of development necessities now.

我认为在现代Web开发中,OOP仍然是主流。 但是我们可以看到,有一些开源项目混合了编程范例并提供了非常合格的框架(例如nest.js )。 由于有React社区,FP现在已成为开发必需品的一部分。

Okay, that’s all for the Redux drill-down. Hope you also get a good understanding about the FP designs in Redux. If you think this article is great, please share it on social networks.

好的,这就是Redux深入分析的全部内容。 希望您也对Redux中的FP设计有一个很好的了解。 如果您认为这篇文章很棒,请在社交网络上分享。

Thank you reading!

谢谢阅读!

  • https://redux.js.org

    https://redux.js.org

  • https://github.com/reduxjs/redux

    https://github.com/reduxjs/redux

  • https://en.wikipedia.org/wiki/Distributive_property

    https://zh.wikipedia.org/wiki/Distributive_property

  • https://en.wikipedia.org/wiki/Associative_property

    https://zh.wikipedia.org/wiki/Associative_property

  • https://medium.com/javascript-scene/10-tips-for-better-redux-architecture-69250425af44

    https://medium.com/javascript-scene/10-tips-for-better-redux-architecture-69250425af44

  • https://code-cartoons.com/a-cartoon-intro-to-redux-3afb775501a6?source=search_post---------3

    https://code-cartoons.com/a-cartoon-intro-to-redux-3afb775501a6?source=search_post---------3

Originally on Pitayan.com

最初在Pitayan.com上

https://pitayan.com/posts/redux-fp-design/

https://pitayan.com/posts/redux-fp-design/

翻译自: https://medium.com/dev-genius/learn-fp-design-from-redux-95cc21479086

redux 函数式组件


http://www.taodudu.cc/news/show-8397540.html

相关文章:

  • html开发软件mac地址,MAC地址的文本框和类
  • Transformer课程 业务对话机器人Rasa 3.x Testing Your Assistant
  • 基于matplotlib以及seaborn对2000年-2015年全球人口预期寿命的分析报告
  • 为什么Creating a tensor from a list of numpy.ndarrays is extremely slow
  • 英语四级试卷上的单词
  • 图文并茂——队列的实现 ,C语言实现
  • 读《春秋》有感之十五:绵上之蒐
  • 张维迎:要坚持的十种人生态度
  • C语言 枚举——称硬币
  • 网络工程师成长日记347-某卷烟厂工程
  • 从装配式建筑流行看云原生技术平台的价值(一)
  • 你只需知道机器人索菲亚曾经说过的话
  • 机器人索菲娜_女机器人索菲亚再添“新技能”
  • 何炅机器人对话_张绍刚和机器人的对话,这个话题让全场都露出了邪恶的笑容!...
  • 狂言要毁灭人类的AI机器人索菲亚 现在想要孩子了
  • 曾扬言 机器人合法公民_当年扬言“摧毁人类”的机器人索菲亚,现怎样了?不怕以后失控吗...
  • 揭开机器人索菲亚的“真面目”:到底是炒作还是科技实力?
  • android移动应用基础教程!微信小程序的事件处理,完整版开放下载
  • mysql 抽取前五条记录
  • 按照日期降序排序,取前五条数据
  • 使用sql语句显示数据库中前五条数据
  • 查询表中第五条到第十条的数据
  • 使用python中的pandas库,读取名为“data”格式为csv的文件,并使用print函数输出读取文件的前五条数据。...
  • linux- iptables四表五链详解
  • css层的定位position、absolute、relative层叠加的五条叠加法则
  • Oracle 查询前10条记录及分页查询(第五条到第十条记录)
  • MSSQL查询第五条到第十条数据
  • SQL查询前五条数据及其他所有数据之和
  • mysql获取每个分类下面的前五条数据
  • 我们所见的微信朋友圈第五条信息流如何出现在我们的眼前的?
  • 这篇关于redux 函数式组件_从Redux学习函数式编程设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/521608

    相关文章

    C++中assign函数的使用

    《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

    MySql基本查询之表的增删查改+聚合函数案例详解

    《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

    PostgreSQL中rank()窗口函数实用指南与示例

    《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

    全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

    《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

    MySQL中的LENGTH()函数用法详解与实例分析

    《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

    MySQL 中的 CAST 函数详解及常见用法

    《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

    Python内置函数之classmethod函数使用详解

    《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

    Python函数作用域示例详解

    《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

    MySQL count()聚合函数详解

    《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

    MySQL 中 ROW_NUMBER() 函数最佳实践

    《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分