概述
之前写了一些 Redux 的一些示例,这次主要是跟着 Redux 官方网站 中的示例继续探索 Redux
Counter Vanilla
demo 代码并在线运行, demo 仅仅使用了 Redux 和原生 JS。当点击按钮时:
- store dispatch 一个 action === 触发一个事件 === 派发一个动作
- 根据操作生成新的 state + 触发一个事件
- store 接收到事件,重新 render
将上述 demo 完善并在线运行
注意: 当有异步操作时,store.dispatch
要在异步之后在去 store.dispatch
React + Redux 示例
这里需要先安装 create-react-app
npm i -g create-react-app
在安全的目录下运行:
create-react-app react-redux-demo
创建完成之后,会有一个提示

之后进入
react-redux-demo
目录下再安装 Redux
// 如果没有 yarn 可以先安装一下
// npm i -g yarn
yarn add redux
之后运行
yarn start
它会默认开一个 3000 端口的本地服务。之后将之前的 Counter Vanilla demo 代码迁移到这个目录下。可以 clone 到本地
git clone https://github.com/bowen-wu/react-first-exploration.git
git checkout d2f85f97a627d374185f01f9cdd7408327c4982a
cd react-redux-example
yarn install
yarn start
之后便在本地运行了,将 Vanilla
升级为 React
之后可以看到:当更新的时候,React + Redux 仅仅会更新该更新的地方,而 Vanilla 会更新整个 App。React 会根据 DOM diff 找到该更新的地方进行局部更新。
但是现在更新 store
的时候有两种方式:
-
index.js
文件将更新store
的方法传给子代,之后子代调用这个方法,从而更新store
- 将
store
传递下去,之后子代自己store.dispatch
index.js
App.js
但是两种方法一种是更新 store
时,逐层调用父组件的方法,一种是将 store
逐层传递下去。一种是一层一层的往上调用,一种是一层一层的往下传。
React-Redux
那么如何解决上述问题,这时可以借助 React-Redux 来解决上述问题。React-Redux 官网。React-Redux 可以让你的 React 组件从 Redux store 中读取数据,并且 dispatch actions 从而更新数据。
React Redux is the official React binding for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update data
- 需要安装 React-Redux
npm install --save react-redux
或者
yarn add react-redux
-
借助 React-Redux 实现上述功能,主要是修改
index.js
和App.js
文件,修改的 diff,最终呈现index.js
文件 和App.js
文件。 -
React-Redux 的相关 Api,它有三个 Api,分别是
Provider
、connect
和connectAdvanced
,其中常用的便是Provider
和connect
,之后看一下关于Provider
和connect
的官方实例
Provider
makes the Redux store available to the rest of your app

connect
React Redux provides a connect function for you to connect your component to the store。connect
接收四个不同的参数,分别为 mapStateToProps
、mapDispatchToProps
、mergeProps
和 options
。

-
connect
的调用方式为connect(mapStateToProps, mapDispatchToProps)(component)
。这种调用方式原理即return
一个函数
connect 调用方式
-
mapStateToProps
: Function ->(state, ownProps?) => Object
-> subscribe Reduxstore
更新,只要store
更新,则mapStateToProps
将会被调用,return Object,这个对象将会合并到组件的props
中,如果不想 subscribestore
更新,可以写null
|undefined
-
state
->mapStateToProps
第一个参数 -> 当store
更新时,mapStateToProps
函数将会被调用,并且传递一个参数store
-
ownProps
-> 如果mapStateToProps
提供了两个参数,那么当store
更新时或者组件接收到新的props
的时候将会被调用,组件的props
作为第二个参数
-
-
mapDispatchToProps
: Function | Object -> Object |(dispatch, ownProps?) => Object
-> 如果定义了函数mapDispatchToProps
,它将带着最多两个参数被调用,返回一个对象,它也会被合并到props
中,用来生成action
相关操作-
dispatch
: Function -> 如果mapDispatchToProps
别声明为一个带有一个参数的函数,它将被dispatch
你的store
-
偏函数
像 connect()()
这种能接收两次参数的函数,把 connect()
叫做偏函数
视图更新过程
当点击 +1
按钮时:
- 调用
this.add1.bind(this)
- 调用
this.props.add1();
,其中this.props.add1
是根据connect
第二个参数而来,即
connect 第二个参数
- 调用
mapDispatchToProps
中的add1
,将会dispatch
一个action
- 之后
index.js
文件中的reducer
接收到action
,执行函数,并且return
新的state
reducer 函数
-
Provider
接收到store
的更新,之后告知所有具有mapStateToProps
参数的connect
,并且mapStateToProps
将会被调用,并且接受新的store
- 页面中如果发现有需要被更新的数据,将会重新渲染( 更新 )
总结
Vanilla.js
- 引入 Redux
- 生成
store
,其中stateChanger
是所有状态变更的过程,即根据action type
返回新的state
let store = Redux.createStore(stateChanger)
- 将
store
放在render
中,render 一下,之后得到了第一次界面render(store);
- 当点击
+1
按钮时,就会触发一个action
,之后就会进入状态变更的逻辑,并且产生一个新的state
- 新的
state
将会导致render
再次运行,之后会获取最新的state
,页面重新渲染数据
React + Redux
与 Vanilla.js 变化在于将 Vanilla.js 变为 React,其他都没有改变。
- 优点:当点击按钮时,只有该更新的地方更新,其他不需要更新的地方将会不更新。
- 第一次
render
时获取到数据,并且将数据传给App
,App
得到数据后,将数据渲染到页面中 - 当点击
+2
按钮时,将会执行父组件的onAdd2
,父组件的onAdd2
将会dispatch
一个action
- 之后就会进入状态变更的逻辑,并且产生一个新的
state
- 之后将会执行
render
React-Redux
与 React + Redux 区别:
- 状态变更时添加一个变量
n
,方便后面使用 - 没有将
store
传给App
, 而是传给了Provider
,优点:Provider
会把store
传给每一个它里面的组件 -
App
通过connect
获取store
,connect
里面将会有获取state
和dispatch
一个action
的相关操作,即mapStateToProps
( 映射 state 到 props ) 和mapDispatchToProps
( 映射 dispatch 到 props ) - 产生新的
state
之后不会执行render
,而是通过Provider
告诉所有组件是否需要更新,如果需要更新将会重新渲染
网友评论