一. Redux简介
1. 什么是Redux
Redux是一个用于JavaScript状态容器,提供可与预测化的状态管理。
Redux可以让你构建一致化的应用,运用于不同的环境(客户端,服务器,原生应用),并且易于测试。
Redux除了和React一起使用外,还支持其他界面库,而且它体小精悍。
2. redux的设计初衷
随着JavaScript单页面开发日趋复杂,JavaScript需要管理更多的state,这些state可能包括服务器响应、缓存数据、本地生成服务器的数据,也包括UI状态等。
管理不断变化的state非常麻烦,如果一个model的变化会引起另一个model变化,那么view变化时,就可能引起对应model以及另一个model的变化,依次可能引起另一个view的变化。所以就会产生混乱。而redux就是为了解决这个问题。
3. Redux的三大核心
-
单一数据源
整个应用的state被存储在一颗object tree中,并且这个object tree只存在唯一一个store中。
-
state是只读的
唯一改变state的方法就是触发action,action是一个描述一发生事件的普通对象
这样确保了视图和网络请求都不能直接去修改state,相反,它们只能表达想要修改的意图,因为所有的修改都被集中化处理,并且按照一个接一个的顺序执行。
-
使用纯函数来执行修改
为了描述action如何改变state tree,你需要去编写reducers
reducers只是一些纯函数,它接收先前的state和action,并且返回新的state。
可以复用、可以控制顺序、传入附加参数。
二. redux的组成
1. State
就是我们传递的数据,那么我们在用React开发项目的时候,大致可以把state分为三类
- DominDate:可以理解为服务端的数据,比如:获取用户的信息,商品的列表等等
- UI State:决定当前展示的状态,比如:弹框的显示隐藏,受控组件等等
- App State:App级别的状态,比如:当前是否请求loading,当前路由信息等可能被多个组件使用到的状态
2. Action
Action是把数据从应用传到store的载体,它是store数据的唯一来源,一般来说,我们可以通过store.dispatch()将action传递给store
Action特点
- Action的本质就是一个JavaScript的普通对象
- Action对象内部必须要有一个type属性来表示要执行的动作
- 多数情况下,这个type会被定义成字符串常量
- 除了type字段之外,action的结构随意进行定义
- 而我们在项目中,更多的喜欢用action创建函数(就是action的地方)
- 只是描述了有事情要发生,并没有如何更新state
3. Reducer
Reducer本质就是一个函数,它用来响应发送过来的action,然后经过处理,把state发送给Store的
注意:在Reducers函数中,需要return返回值,这样Store才能接收到数据
函数会接收两个参数,第一个参数是初始化state,第二个参数是action
4. Store
Store就是把action与reducers联系到一起的对象
主要职责
- 维持应用的state
- 通过createStore来构建store
- 提供getState()方法获取action
- 提供dispatch()方法发送action
- 通过subscribe()来注册监听
- 通过subscribe()返回值来注销监听
三. Redux入门案例
1. 准备工作:
- 构建react项目:
npx create-react-app redux-demo
-
删除多余文件
-
在src下创建pages文件夹,在pages文件夹下创建home文件夹,在home文件夹下创建Home组件
-
编写一个简单的结构样式
import React, { Component } from 'react'; class Home extends Component { render() { return ( <button>点我点我,发送一个action</button> ); } } export default Home;
-
在App.js中引入这个组件
import React from 'react'; import Home from './pages/home' function App() { return ( <div className="App"> <Home /> </div> ); } export default App;
-
安装redux
2. 创建一个Action
-
在src目录底下创建一个文件夹action
-
在该目录下创建一个index.js文件用来构建Action
-
在action创建函数里面利用return返回一个action对象,注意需要携带type属性
-
把这个action创建函数进行导出
const sendAction = () => { return { type: 'send_type', value: '我是一个action' } } module.exports = { sendAction }
3. 创建一个Reducer
-
在src目录下创建一个文件夹reducers
-
在该目录下创建一个index.js文件用来创建reducers,注意reducers要接收两个参数
-
第一个参数是state,我们可以定义一个初始化state,然后进行赋值
-
在函数里面判断第二个参数action的type值是否是我们发送的
-
如果是的话,我们可以通过return返回新的state
-
把reducer进行导出
const initState = { value: '默认值' } const reducer = (state = initState, action) => { switch(action.type) { case 'send_type': return Object.assign({ }, state, action); default: return state } } module.exports = { reducer }
4. 创建一个Store
-
在src目录下创建一个文件夹store
-
在该目录下创建一个index.js文件用来构建store,注意createStore函数里面第一个参数接收的是reducers
-
我们需要导入刚刚创建的reducers,然后设置到函数里面去
-
createStore的返回值就是我们构建好的store,然后进行导出
import { createStore} from 'redux'; import { reducer} from '../reducer'; const store = createStore(reducer); export default store;
5. 在Home组件开始使用
-
在页面中的button按钮绑定一个点击事件
-
在组件加载完毕的时候我们通过store来进行 监听器 的注册,返回值可以用来注销监听
-
在点击事件处理函数中,通过store.dispatch来发送一个action
import React, { Component } from 'react'; import store from '../../store'; import { sendAction} from '../../action'; class Home extends Component { handClick = () => { const action = sendAction(); store.dispatch(action)