学习目的
了解和熟练使用 Redux,能够在实际项目中运用。
学习方法:类比 VueX
Redux 比较 难 学,要多按照 步骤 练习,要多码 最简单的 文中的示例。
Redux介绍
Redux不是必须的
如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
什么情况下需要使用 Redux
① 某个组件的状态,需要共享
② 某个状态需要在 任何地方 都可以拿到
③ 一个组件需要改变全局状态
④ 一个组件需要改变另一个组件的状态
这点和 VueX 基本一致,毕竟都是状态管理工具。
Redux 安装
npm install --save redux
在入口文件 index.js引入 import { createStore } from 'redux';
Redux 三大原则
① 单一数据源
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
② State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
③ 使用纯函数来执行修改
为了描述 action 如何改变 state tree ,你需要编写 reducers。
Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state;
Redux 工作流程
用户发出 Action---------store.dispatch(action);
Store 自动调用 Reducer,并且传入两个参数:当前 State 和 收到的 Action。 Reducer 会返回新的 State ---------------- function counter(state=0, action){ return Newstate }
State 一旦有变化,Store 就会调用监听函数-------------store.subscribe(render);这时可以触发重新渲染 View。
Redux 基本概念
① Store
Store 就是保存数据的地方,跟 VueX 定义的 store 一样,整个应用只能有一个 Store。
Store 将state, action 与 reducer 联系在一起的对象
store包含了完整的 state 和 reducer
定义 store
const store = createStore( reducers )
内部会第一次调用reducer函数,得到初始state,所以switch的default必须返回state!!
核心方法:getState( ) :得到state
dispatch(action) :分发action,触发reducer调用, 产生新的state
subscribe(listener):注册监听,当产生了新的state时, 自动调用
② Action
action 作用于 store,标识要执行行为的对象
包含2个方面的属性
1) type : 标识属性, 值为字符串, 唯一, 必要属性
2) xxx : 数据属性, 值类型任意, 可选属性
例子:
const action = {
type: 'INCREMENT',
data: 2
}
Action Creator( 创建Action的工厂函数 )
const increment = (number) => ({type: 'INCREMENT', data: number})
③ Reducer
Reducer 是相应的抽象,是纯方法,传入旧状态state 和 action ,返回新状态。
注意
1)返回一个新的状态
2)不要修改原来的状态
步骤:1定义规则,即 reducer switch
2根据计算规则 生成 store const store = createStore(fn) ;
3 定义数据(即state)变化之后派发规则 subscribe
4 触发数据变化 dispatch
具体示例步骤
components 中写 app.jsx 组件
index.js
Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
① redux / action-types.js
② redux / actions.js
改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。
③ redux / reducers.js
定义规则,即 reducer / switch
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
④ components / app.jsx
⑤ redux / store.js
Redux 提供 createStore 这个函数,用来生成 Store。
createStore 函数接受另一个函数(counter)作为参数,返回新生成的 Store 对象。以后每当store.dispatch发送过来一个新的 Action,就会自动调用 Reducer,得到新的 State。
React-Redux 的用法
Redux 上述写法的问题
1) redux与react组件的代码耦合度太高
在react组件 app.jsx 中写 redux 代码, 耦合度 太高
2)编码不够简洁
例如,this.props.store.dispatch(actions.increment(number))
React-Redux 是 一个react插件库,专门用来简化react应用中使用 redux,React-Redux 将所有组件分成两大类: UI组件 和 容器组件
UI组件
1)只负责UI的呈现,不带有任何业务逻辑
2)通过props接收数据(一般数据和函数)
3)不使用任何Redux的 API
4)一般保存在components文件夹下
容器组件(containers)
1)负责管理数据和业务逻辑,不负责UI的呈现
2)使用Redux的 API
3)一般保存在containers文件夹下
核心API
connect( )
将 UI组件 包装成 容器组件
import { connect } from 'react-redux'
connect( mapStateToprops, mapDispatchToProps )( Counter )
mapStateToProps( )
将外部的数据(即state对象)转换为UI组件的标签属性
const mapStateToprops = function (state) { return { value: state } }
mapDispatchToProps( )
将分发action的函数转换为UI组件的标签属性
简洁语法可以直接指定为actions对象或包含多个action方法的对象
<Provider>组件
让所有组件都可以得到state数据
<Provider store={ store }>
<App />
</Provider >
安装 react-redux :npm install --save react-redux
具体示例步骤
redux/action-types.js
不变
redux/actions.js
不变
redux/reducers.js
不变
components / counter.jsx UI组件
完全没有 redux 代码 ,和普通的 ui 组件一样
containters/ app.js
index.js
redux异步编程
redux默认是不能进行异步处理的,但是实际中又需要在redux中执行异步任务(ajax, 定时器)。
下载redux插件(异步中间件)
npm install --save redux-thunk
index.js
redux / actions.js
components/counter.jsx
containers/app.js
redux调试工具
① 安装chrome浏览器插件 redux-devtools.crx
② 下载工具依赖包 npm install --save-dev redux-devtools-extension
打开浏览器,F12