redux是什么
Redux一个用于应用程序状态管理的开源JavaScript库。Redux经常与React搭配运用,但其也可以独立使用。
为什么用redux
多个组件(包括页面)依赖于同一个状态,而该状态发生变化怎么通知到所有组件?
如果不使用redux或其他状态管理工具, 代码又没遵循一定规范,很容易把代码写的一团糟。
我们需要一定的机制,可以在同一个地方查询状态、改变状态、传播状态的变化。
这时redux就是你想要的工具。
设计思想
- Web 应用是一个状态机,视图与状态是一一对应的。
- 所有的状态,保存在一个对象里面。
基本概念和 API
1. Store
Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
Redux 提供createStore这个函数,用来生成 Store。
1 | import { createStore } from 'redux'; |
上面代码中,createStore函数接受另一个函数(其实就是一个总的reducer函数)作为参数,返回新生成的 Store 对象。
1 | import { applyMiddleware, createStore } from 'redux'; |
上面代码createStore多了一个参数——中间件,你可以添加各种中间件,常用中间件如“redux-logger”, “redunx-thunk”
2. State
Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
当前时刻的 State,可以通过store.getState()拿到。
1 | import { createStore } from 'redux'; |
3. Action
State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。
Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置
1 | const action = { |
上面代码中,Action 的名称是 USER_LOGIN_SUCCESS,它携带的信息是 user对象。
可以这样理解,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。
Action Creator
View 要发送多少种消息,就会有多少种 Action, 同一Action可能在不同地方发出。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator。
1 | const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS'; |
store.dispatch()
store.dispatch()是 View 发出 Action 的唯一方法。
1 | dispatch({ |
结合 Action Creator,这段代码可以改写如下。
1 | store.dispatch(loginSuccess(user)) |
Reducer
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
1 | const authReducer = (state = initialState, action = {}) => { |
store.dispatch方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。
1 | import { createStore } from 'redux'; |
store.subscribe()
Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
1 | import { createStore } from 'redux'; |
显然,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listener,就会实现 View 的自动渲染。
1 | function listerner() { |
异步操作
异步操作至少要送出两个 Action:用户触发第一个 Action,这个跟同步操作一样,没有问题;如何才能在操作结束时,系统自动送出第二个 Action 呢?
一般dispath只接受对象当参数
1 | // authActions.js |
1 | // loginScreen.js |
使用“redux-thunk”中间件后,dispath被改造成可以接受函数当参数,这样就能实现异步操作了
在authAction.js中新定义一个actionCreator
1 | function login(phoneNum, password) { |
1 | // loginScreen.js |
这样代码看起来更优雅了
React-Redux
为了方便使用,Redux 的作者封装了一个 React 专用的库 React-Redux