以前在有道云笔记上写过一篇 Redux 学习实践的文章,附带了一个小 Demo。因为一段时间没看 Redux,加上以前缺少足够的练习,如今想重构我的博客,使用 Redux 进行状态。如今不得不回头再看看 Redux 相关东西。这里顺便记录下学习笔记,一来便于回顾,二来但愿对他人有所帮助。笔记同步写在我的博客网站java
这篇文章是知识点的梳理,若是你对 Redux 的基础有必定了解,阅读起来可能比较合适。react
Redux 能够说是 Flux 架构思想的最佳实践方案,用于对大型、复杂、多数据来源的 React 进行数据管理。遵循 Redux 的设计原则,再配合 React 容器组件、展现组件分离的代码组织原则,可让咱们的项目结构清晰,数据流清晰,十分利于项目的维护开发。git
关于这三大原则的深刻理解建议参考 《深刻React技术栈》、《深刻浅出React和Redux》github
有 MVC 框架使用经验的同窗应该清楚,MVC 的工做过程是这样:view 层将用户行为传递到 controller 中的action, controller 中的 action 和 Model 层交互操做数据,返回到 view。一般 MVC 框架的实现 M 和 V 层是能够交互的,这样数据就不是单向流动,这种设计不少场景下很灵活,写起来很爽快,可是要项目过大,项目数据流复杂,项目维护就不爽了。redux
Redux 则严格遵循上面提到的设计三大原则,工做过程是这样的:view 层触发一个 action,这个 action 由 store.dispatch(action) 传递给 reducer,reducer 根据 previousState 和 action type 返回一个新的 state(不修改数据), 如此实现了数据的变动。数组
上面 Redux 的工做过程提到了 Redux 有 store、action、reducer 这些概念,这些都是 Redux 对外提供的核心 API,咱们来看看他们分别是干吗的。bash
store架构
store 做为整个应用数据的惟一来源,用于保存数据和 dispatch action。store 使用 Redux 提供的 createStore 方法来生成。框架
import { createStore } from 'redux';
let store = createStore(reducer)
复制代码
createStore 接受一个 reducer 做为参数,返回一个 store 对象。store 对象包含 4 中方法:dom
getState():// 用于获取 store 中当前的状态
dispatch():// 用于分发 action,这个是改变 store 中数据的惟一方式
subscribe(listener):// 注册一个监听者,在 store 发生变化时被调用
replaceReducer(nextReducer):///更新当前 store 中的 reducer
复制代码
reducer
reducer 本质上是一个函数,这个函数能接受一个 action 和一个旧的状态(previousState),根据 previousState 和 action 返回新的状态
reducer(previousState, action) => newState
复制代码
reducer 必须是一个纯函数,不能修改原来状态,关于纯函数的概念请阅读其余资料学习。
action
reducer 的 action 本质上是一个 javaScript 对象,这个对象必须有一个 type 属性,用来代表 action 的类型,还能够有 payload, error, meta 属性。关于 action 对象的属性,社区有个规范,能够参考github.com/redux-utili…
const action = {
type: 'ADD_TODO',
payload: 'todo'
}
复制代码
reducer 就是根据 action type 属性来决定返回新的 state。
我在学习 Redux 的时候,看了不少文档,认为对 Redux 的概念了然于胸,可是动手写第一个小 Demo 的时候仍然以为很难下手,多是 Redux 这些概念对我而言太新。这里给出我写的第一个小 Demo。
这个 Demo 实现了点击按钮让数字加一减一的功能,没有任何复杂度,单纯的是为了了解 action
、store
、reducer
的具体做用和协做关系。
Demo 地址: github.com/wewin11235/…
为了便于观察,Demo 的代码都丢在了一个文件里,在实际开发中,必定要遵循好的代码组织原则。
import React from 'react';
import ReactDOM from 'react-dom';
// 建立 action
// action 是 javaScript 对象,是用户行为的抽象,必须包含一个 stype 字段
// 根据 Demo 须要实现记数功能,抽象出两种 action, 一种表示加,一种表示减
const incream_action = { type: 'INCREAM' };
const decream_action = { type: 'DECREME' };
// 建立 reducer
// reducer 接受一个 previousState 和 action 返回一个新的 state
const reducer = (state=0, action) => {
switch (action.type) {
case incream_action.type:
return state + 1;
case decream_action.type:
return state - 1;
default:
console.log('default');
return state;
}
}
// 建立 store
// store 建立使用 createStore(reducers)
// createStore 由 redux 提供
import { createStore } from 'redux';
let store = createStore(reducer);
// 建立计数组件
class Counter extends React.Component {
constructor(props) {
super(props);
}
render() {
const { count, doIncrement, doDecrement } = this.props
return(
<div>
<span>{count}</span>
<button onClick={doIncrement}>+</button>
<button onClick={doDecrement}>-</button>
</div>
)
}
}
const render = () => ReactDOM.render(
<Counter
count={store.getState()}
doIncrement={() => store.dispatch(incream_action)}
doDecrement={() => store.dispatch(decream_action)}
/>,
document.getElementById('root')
);
render();
// 为了能在 store 发生变化后能刷新页面,须要给 store 注册一个监听事件
// store 变化后,刷新页面
store.subscribe(render);
复制代码
最小 Redux 应用诞生。
欢迎指正,补充!