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

    相关文章

    Spring组件初始化扩展点BeanPostProcessor的作用详解

    《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

    C语言字符函数和字符串函数示例详解

    《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

    Java进阶学习之如何开启远程调式

    《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

    kotlin中的行为组件及高级用法

    《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

    MySQL中COALESCE函数示例详解

    《MySQL中COALESCE函数示例详解》COALESCE是一个功能强大且常用的SQL函数,主要用来处理NULL值和实现灵活的值选择策略,能够使查询逻辑更清晰、简洁,:本文主要介绍MySQL中C... 目录语法示例1. 替换 NULL 值2. 用于字段默认值3. 多列优先级4. 结合聚合函数注意事项总结C

    Java8需要知道的4个函数式接口简单教程

    《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

    MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

    《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

    golang panic 函数用法示例详解

    《golangpanic函数用法示例详解》在Go语言中,panic用于触发不可恢复的错误,终止函数执行并逐层向上触发defer,最终若未被recover捕获,程序会崩溃,recover用于在def... 目录1. panic 的作用2. 基本用法3. recover 的使用规则4. 错误处理建议5. 常见错

    Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

    《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

    Vue ElementUI中Upload组件批量上传的实现代码

    《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl