剑客
关注科技互联网

实例讲解Redux

实例讲解Redux

示例代码地址在 这里
,你可以通过 git clone
命令clone到本地,也可以直接下载。

然后通过执行 npm install
安装所依赖的模块 。之后便可以通过 node
执行示例代码。

什么是Redux

随着 JavaScript 单页应用开发日趋复杂, JavaScript 需要管理比任何时候都要多的 state (状态)
。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。

简单来说 Redux
就是 javaScript
的状态管理器。同时, Redux
支持 React
Angular
Ember
jQuery
等。

到这里你可能并不知道该如何使用 Redux
,别着急,在了解如何使用之前,需要先理解相关的基本概念。示例代码可查看 demo1/app.js

State

在一个可以进行用户交互的界面上,当我们触发了交互事件的时候,界面也会跟着进行更新。例如在一个app中的下拉刷新,当我们进行下拉刷新这个动作时,会去请求服务器数据,当返回结果时app的页面会更新。界面的改变我们就可以看做是状态的变化。而状态的变化是由于我们进行了某个动作。在Redux中,尤其需要注意的是 State是只读的
,且状态的变化只能通过Reducer函数进行转换,

Action

Action就是你与界面进行交互的行为。它是一个对象且
必须要包含一个 type
属性

,用来描述你要做的是什么事。

Store

Store
就是应用状态的容器。用来维护应用的 state
、获取 state
、更新 state
、监听 state
变化等。这里需要注意的是
整个应用只有一个 Store

Reducer

一个纯函数,接收当前的 state
和一个 action
参数,根据当前的行为,即 action
type
属性返回一个新的 state
。状态的更新只能通过这个函数。

Talk is cheap, Show me the code!

可能看了上述内容你仍然不知道什么是 Redux
Redux
能干什么 。下面结合实例 demo1/app.js
中的内容理解上述概念。

1.引入相关模块(这里没有使用 ES6
的方式是为了能使用 node
命令直接查看结果, node
命令无法识别 import
。当然你也可以通过配置 babel
的方式使用 import
语法)

var { createStore } = require('redux');
//import { createStore } from 'redux' //es6方式引入

2.定义 Reducer
,来进行状态的更新

var defaultState = 'JavaScript'
function programLanguage(state = defaultState, action) {
    switch (action.type) {
        case 'IOS':
            return action.language;
        case 'WEB':
            return action.language;
        case 'SNACK':
            return action.language;
        default:
            return state;
    }
}

从上述代码可以看到,我们定义了一个 programLanguage
方法,其实这就是一个 Reducer
,它接受了当前 state
action
参数。用来更新 state

3.创建 store

let store = createStore(programLanguage);

再次强调整个应用中只能有一个 store
,即 createStore
函数只能被调用一次。

createStore
的定义如下:

function createStore(reducer, preloadedState, enhancer);

可以看到的是createStore接受三个参数

  • reducer:就是上述的reducer函数,这里不再赘述

  • preloadedState: 初始state

  • enhancer:组合store creator的高级函数,返回一个新的强化过的store creator。

4.更改应用的状态

store.dispatch({ type: 'default' });
store.dispatch({ language: 'Swift', type: 'IOS' });
store.dispatch({ language: 'Ruby', type: 'WEB' });
store.dispatch({ language: 'Python', type: 'SNACK' });

通过 dispatch
方法将 action
发送到 reducer
函数中,进行状态的更新。

执行 node demo1/app.js
的打印结果如下

JavaScript
JavaScript Swift
JavaScript Swift Ruby
JavaScript Swift Ruby Python

当执行第一句代码 store.dispatch({ type: 'default' });
时 返回的是JavaScript。是由于dispatch方法内部会调用在 createStore
中注册的 Reducer
函数,即 programLanguage
函数。由 programLanguage
的内部逻辑 return
的是一个 defaultState
。此时整个应用的状态为 JavaScript

当执行第二句代码 store.dispatch({ language: 'Swift', type: 'IOS' });
时 返回了 JavaScript Swift
。是由于 type
IOS
, programLanguage
返回的是 state + ' ' +action.language;
因为上一句代码将应用的状态变为了 JavaScript
,所以结果自然就是 JavaScript Swift
。同时整个应用的状态也会变成 JavaScript Swift

同理,第三句和第四句代码也是如此。

5.订阅状态的更新

store.subscribe(() =>
    console.log(store.getState())
);

为了方便查看状态的变化。这里调用了 subscribe
方法,每当状态发生变化时都会调用其回调函数。

store.getState()
获取应用的当前状态。

优化操作

Action creator

随着页面的增加, Action
必然也会越来越多,如果 Action
内部所携带的消息也很多。此时如果需要状态的更新,就需要写复杂的 Action
,造成代码可读性差,文件臃肿。所以我们可以使用 Action creator
来构造 Action
。当需要进行状态更新就传入相应的数据到 Action creator
中生成 Action
并返回。

demo2

我们创建了一个 HomeAction
的文件专门用来存放 Action Creator
。在此文件中我们创建了三个 Action creator
,分别是 action_ios
action_web
action_snack
,并将创建 Action
的任务交给这三个函数。

与此同时在我们 demo2/app.js
中需要 dispatch
一个 action
的时候。只需要从 Action creator
中取出 Action
就行了。并不需要我们手动的去创建,如此一来便大大增加代码的可读性,可维护性。

分散Reducer

同样的随着业务量的增加, Reducer
必定也会越来越大。所以我们可以按模块的不同来拆分Reducer。将一个大的 Reducer
拆分成几个小的 reducer

demo3
reducer
文件夹中,我们按照模块的不同的拆分 homeReducer
profileReducer
。分别用来处理 home
页面和 profile
页面状态的更新。

那么问题来了,这么拆分如何使用 createStore
去创建 store
呢,毕竟 createStore
只能传一个 Reducer
参数。而且 createStore
只能调用一次。

别着急,在 redux
中提供了一个 combineReducers
的方法,用来组合我们的 Reducer

const mainReducer = combineReducers({
    homeReducer,
    profileReducer
})
let store = createStore(mainReducer);

最后

谢谢阅读,如果感觉本文对你有用,那将是我的荣幸。如果有写的错误的地方也请留言指正。当然也可以加我QQ 757766483给我留言。

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址