Redux 能做什么?

简介:

一、我先给一个 Redux 的定义

Redux 被大家知道应该都是来自于 React 的出现,但是这篇文章会通过介绍一个 React 之外的例子,来让大家理解 Redux 是什么东西,到底还能够做点撒。

我自己的理解是:

Redux 是一个改变状态(state)的模型,这个模型通过一个单向操作的方式来改变状态,用数学符号的方式来理解我认为应该是:y = f(x),嗯,就是一个最简单的函数模型。

不过这样说,有些人还会不理解,毕竟以前撸代码不是这个样子的,那么我们先反向的来获取自己的理解。

首先,我们需要知道 Redux 有的以下几个东西:

createStore
reducer
dispatch

我觉得需要介绍清楚 Redux ,知道这三个就行了,至于还有一些函数我觉得都是调味料,这里先不介绍。

好吧,现在我就把上面的数学函数模型语义的转换一下(也许不一定对,但是可能暂时这样理解,理解是一个过程):

第一步:newState = store(reducer)(state)
第二步:newState = reducer(state)
为什么这里可能理解成两个步骤呢?那是因为我们可以从不同的层面去认识 Redux,在第一步中我的理解是store里面的东西(reducer)去改变了 state,而在第二步中,我以实际会起到作用的层面去理解,就是 reducer 去改变了 state。

好吧,来个对比:

y = f(x)
newState = reducer(state)

最后我自己先得出一个结论:

f <=> reducer ( <=>: 表示等价的意思)

好吧,废话就上面那么多了,接下来我举一个实际的例子来理一下自己对 Redux 的理解,这个例子是我在一篇文章中看到的,觉得不错。

二、 先介绍一下这个例子的效果


ddbf6fae0cb18676a5787b722bdc18f0f3e92779

这里我们要实现的效果就是:

点击飞机,让飞机随机移动到一个新的坐标点

这里我们可以理解为:新坐标[x1, y1] = f(原始坐标[x0, y0])

三、开始撸一个实例

1.首先我们需要定义个 f 来修改坐标

/**
 * reducer
 * @param state 坐标状态
 * @param action 执行的行为
*/
function coordinates(state = [1, 1], action) {
    switch (action.type) {
        case CLICK:
            return [
                state[0] + 40 * Math.random(),
                state[1] + 40 * Math.random()
            ]
        default:
            return state;
    }
}

这个函数主要就是使初始坐标 [1, 1] => [1 + random, 1 + random] 这样返回一个全新的数组,这个全新的数组就是新的状态。

2.我们再将这个 f 函数给 Redux 的 Store 去管理

/**
 * 创建 Redux 的 Store(存储器)
*/
let store = createStore(coordinates);

这个比较简单,就是通过传入 f 来创建一个 Store,对于 Redux 来说有且只有一个 Store,这个和 flux 有比较大的差别。

3.然后再定义一个行为,使我们能够通过 dispatch 调用这个行为去改变 state

/**
 * action
*/
const CLICK = 'CLICK';
/**
 * @returns plainObject => action
 */
function click() {
    return {
        type: CLICK
    }
}

在 Redux 中,只有通过 dispatch 方法去改变状态,就是因为这样,才让我们调试代码变得简单,复现 BUG 更加容易,因为它是单向的,顺着一个方向在流动数据。

4.接下来就写一下 dispatch

plane.events.onInputDown.add(() => {
    store.dispatch(click())
}, null);

先抛开其他代码,我们剥离一下:

store.dispatch(click())

这样就会去调用行为,然后执行我们上面定义的 coordinates 函数,返回一个新的坐标

5.最后我们再订阅一下具体改变我们飞机位置的业务代码

上面的写完后,我们只是返回来状态,但是还没体现到飞机在场景下的移动效果。我们能够通过

store.getState()

来获取最新的当前状态,其实在 Redux 源代码里面就是很简单的一个函数:

function getState() {
    // 这里的 currentState 是一个外部的变量,在 Store 的作用域下全局生效
    return currentState;
}

好吧,现在我们让飞机订阅一下移动的函数:

/**
* 定义 plane(飞机) 的移动
*/
function movePlane(plane) {
    game.add.tween(plane).to({
        x: store.getState()[0],
        y: store.getState()[1]
    }, 1000, 'Linear', true);
}
/**
* 移动事件的订阅
*/
store.subscribe(movePlane.bind(null, plane));

大家会想,为什么我订阅了就自动调用 movePlane 生效了呢?在 Redux 内部会调用当前的监听器,源代码如下,很简单,监听器就是一个数组来装的,最后移出来执行一下:

function subscribe(listener) {
    var isSubscribed = true;

    ensureCanMutateNextListeners();
    nextListeners.push(listener);

    // 然后会返回一个取消订阅的函数,这里省略
}
function dispatch(action) {
    // 省略一些杂七杂八的异常处理代码

    try {
        isDispatching = true;
        currentState = currentReducer(currentState, action);
    } finally {
        isDispatching = false;
    }

    // 执行的代码
    var listeners = currentListeners = nextListeners;
    for (var i = 0; i < listeners.length; i++) {
        listeners[i]();
    }

    return action;
}

好吧,这样就是一个游戏的流程来,在 Redux 的帮助下,很好的组织了代码,优雅的完成了。执行代码的流程是这样的:

dispatch(click()) => update reducer => subscribe() => 飞机移动新位置

文章转载自 开源中国社区 [http://www.oschina.net]

相关文章
|
区块链 开发者
教程(1):关于如何上链的简单直接的操作教程
这是一篇关于如何上链的简单直接地操作流程。
1742 0
教程(1):关于如何上链的简单直接的操作教程
|
5月前
|
安全 算法 Ubuntu
Linux(openssl)环境:编程控制让证书自签的技巧。
总结:在Linux环境中,OpenSSL是一个非常实用的工具,可以帮助我们轻松地生成自签名证书。通过上述三个简单步骤,即可为内部网络、测试环境或开发环境创建自签名证书。但在公共访问场景下,建议购买经过权威认证机构签发的证书,以避免安全警告。
244 13
|
8月前
|
机器学习/深度学习 存储 编解码
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
360 7
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
|
8月前
|
人工智能 云计算 数据中心
阿里云当选UALink联盟董事会成员,推进新一代GPU互连技术!
阿里云当选UALink联盟董事会成员,推进新一代GPU互连技术!
344 2
|
8月前
|
人工智能 数据管理 数据库
Data+AI用户体验升级,阿里云「DMS+UX」焕醒数智一体化新体验
Data+AI用户体验升级,阿里云「DMS+UX」焕醒数智一体化新体验
211 0
|
11月前
|
搜索推荐 Android开发 iOS开发
安卓vs. iOS:操作系统的终极对决####
本文探讨了安卓和iOS两种主流移动操作系统的特点,从用户体验、系统生态、硬件兼容性等维度进行对比分析。通过深入浅出的方式,揭示了两者在技术层面的优劣及未来发展趋势,旨在帮助用户更好地理解并选择适合自己的平台。 ####
ly~
|
12月前
|
人工智能 自然语言处理 搜索推荐
人工智能在医学领域的应用
人工智能在医学领域的应用广泛,涵盖医学影像分析、医疗数据分析与预测、临床决策支持、药物研发、自然语言处理及智能健康管理等方面。它能提高诊断准确性,预测疾病风险与进展,优化治疗方案,加速药物研发,提升手术安全性,并实现个性化健康管理,有效推动了医疗科技的进步。
ly~
548 3
|
移动开发 JavaScript 数据管理
HTML5 拖放在游戏中的应用
HTML5的拖放功能在游戏开发中广泛应用,尤其在创建交互式网页游戏时。它支持多种场景,如拖动角色或物品、选择和装备物品、拼图或配对游戏以及自定义界面布局。通过简单的HTML和JavaScript代码,可实现流畅的拖放交互,并提供视觉反馈,增强用户体验。此外,还需考虑设备兼容性和数据管理,确保游戏在不同设备和浏览器上都能良好运行。总之,HTML5拖放功能使网页游戏更生动有趣。
|
存储 监控 安全
内存卡数据恢复,3个方法帮你找回丢失的照片和视频
今天,针对内存卡数据恢复,本期做一个详细的归纳,分析常见的数据丢失原因、详细的数据恢复步骤、以及如何保护内存卡数据。
内存卡数据恢复,3个方法帮你找回丢失的照片和视频
|
Dart 搜索推荐 IDE
打造个性化天气应用:从零开始的Flutter项目之旅
【8月更文挑战第31天】本文将引导读者通过Flutter框架创建一个简单的天气应用,涵盖从设置开发环境到实现基本功能的全过程。我们将探索如何使用Dart语言和Flutter SDK构建用户界面,并集成第三方API来获取实时天气数据。文章不仅提供代码示例,还将讨论如何进行调试和部署应用,确保读者能够理解并实践所学知识。