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

    相关文章

    Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

    《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

    shell编程之函数与数组的使用详解

    《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

    MySQL高级查询之JOIN、子查询、窗口函数实际案例

    《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

    SpringQuartz定时任务核心组件JobDetail与Trigger配置

    《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

    MySQL中FIND_IN_SET函数与INSTR函数用法解析

    《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

    C++ Sort函数使用场景分析

    《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

    C语言函数递归实际应用举例详解

    《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

    C/C++错误信息处理的常见方法及函数

    《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

    Kotlin 作用域函数apply、let、run、with、also使用指南

    《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

    Android Kotlin 高阶函数详解及其在协程中的应用小结

    《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda