本文介绍 redux 的基本使用,介绍 redux 的流程。以及 react-redux 的基本使用
一、redux 的工作流程
上面这幅图即redux 的工作流程。可以看出,首先视图层(component)如果需要数据不能直接访问
Store
,通过 Store的dispatch
来触发一个action
,随后,Store
会交给Reducers
去处理这个action
,这个reducer
会接收两个参数,分别是 previousState(当前的state) 以及 action(当前的action)。经过reducer
的处理之后,会返回一个新的state
给store
,然后store
再将一数据分发给 组件。
二、基本使用
下面根据这个流程应用redux来写一个简单的样例:
计数器的实现
- 首先安装redux
npm i redux --save --registry=https://registry.npm.taobao.org
- 创建
store
import { createStore } from 'redux'
import reducer from './reducer'
export default createStore(reducer)
createStore 接受了一个参数,他就是 reducer,实际应用中 reducer不用我们去手动调用,当 reducer 作为 createStore的第一个参数时,在store.dispatch方法会触发 Reducer 的自动执行
- 创建
reducer
export default (state = {count: 0}, actions) => {
switch(actions.type) {
case 'ADD_COUNT':
return { count: state.count + 1}
default:
return state
}
}
reducer 是一个函数,接受两个参数,分别是 state,和 action
- 编写
计数器
import React from 'react'
import store from './store'
export default class Count extends React.Component {
constructor(props) {
super(props)
this.state = store.getState()
store.subscribe(this.storeChange)
}
storeChange = () => {
this.setState({
...store.getState()
})
}
clickHandle = e => {
store.dispatch({
type: 'ADD_COUNT'
})
}
render() {
return (
{this.state.count}
)
}
}
首先,导入store。在 constructor 中通过 store.getState() 来获取 store
然后,通过store.subscribe 来进行订阅。当数据发生改变是,执行 storeChange 方法
最后,在 button 点击时,回去触发 事件处理函数,在这个事件处理函数中。通过 store.dispatch() 方法,去提交一个 action 来匹配reducer 中的对于项改变数据。
来整理一下这个过程:
- 按钮点击 触发事件处理函数(
clickHandle
)- 在事件处理函数内,
store.dispatch(action)
。来提交这个action
store
接受到这个action
后,把它交给reducer
来进行处理reducer
根据当前action
的type
值 来进行对应的处理。然后返回一个新的state
- 当
store
监听到数据变化时,就会执行之前订阅的store.subscribe(this.storeChange)
中的storeChang
e这个方法- 当执行
setState
之后,render()
会重新渲染,span
标签内部的值也会更新。
在实际的项目开发中,应该让文件尽量的低耦合,比如在 count.jsx 中,可以把 action 提取出去。为此你可以创建一个 文件夹 来存放redux 相关的代码。
例如:
redux\store\index.js
redux\reducers\index.js
redux\actions\index.js
比如 actions。一般会将 type 字段定义一个文件,然后使用一个 静态的工厂函数来生成 action
// actionTypes.js
export const ADD_COUNT = 'addCount'
// ...
// createActions.js
import { ADD_COUNT } from './actionTypes'
export const addCount = () => {
return {
type: ADD_COUNT
}
}
// count.jsx
import { addCount } from './redux/actions/createAction.js'
store.dispatch(addCount())
action 中, type 字段为必须字段,其他的可以根据需求增加,比如你想传递更多的数据。
三、react-redux
react-redux 是一个插件,内置的一些 API 可以简化我们在 react 中使用 redux
- 安装
npm i react-redux --save --registry=https://registry.npm.taobao.org
react-redux 提供了 两个方法 分别是 Provider
和 connect
3.1、 Provider
// app.js
import {Provider} from 'react-redux'
impor store from './redux/store/index.js'
ReactDOM.render(
)
基本使用即,使用Provider将根组件包裹,在 Provider 中传递一个 store 属性,挂载当前 redux 的 store。此后,其中的后代组件就不用再去应用 store进行一些列的操作。但是在这之前需要组件建立映射的关系。就需要后面的 connect 方法
3.2、connect
connect 接受两个参数,分别要表示你的 输入
和 输出
。最后返回一个新的函数
下面修改之前的 Count.jsx
// Count.jsx
import React from 'react'
import store from './store'
import { connect } from 'react-redux'
class Count extends React.Component {
constructor(props) {
super(props)
this.state = store.getState()
store.subscribe(this.storeChange)
}
storeChange = () => {
this.setState({
...store.getState()
})
}
render() {
return (
{this.props.count}
)
}
}
const mapStateToProps = state => {
return {
count: state.count
}
}
const mapDispatchToPtops = dispatch => {
return {
clickHandle() {
dispatch({type: 'ADD_COUNT'})
}
}
}
export default connect(mapStateToProps, mapDispatchToPtops)(Count)
建立好映射关系之后,通过 this.props 访问store
以上即 redux 和 react-redux 最基本的使用方式。其他更详细的使用方法以及使用规范可以参考其他优秀的博文以及官方文档。