redux简介
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。Redux 除了和 React 一起用外,还支持其它界面库。
安装
使用npm安装npm install --save redux
或者使用yarn安装yarn add redux
redux flow
三大原则
- 唯一数据源
- 保持只读状态
- 数据改变只能通过纯函数来执行
这里的纯函数指的就是reducer,随着应用变大,可以拆分成多个reducer
核心
Action
action负责将数据从应用传输到store,通过store.dispatch()将action传到store;action本质上是JavaScript对象,通过键值来传递数据,规定必须要有type
属性,通过type来标识action,此外可以添加其他属性,结构如下:
{
type: 'ADD_ITEM',
content: 'code review'
}
Reducer
reducer的主要功能是将action发送到store从而更新store,(previousState, action) => newState
,reducer函数接收两个参数,一个是旧的state,另一个是action,返回值是一个新的state。reducer通过action的type属性来识别不同的操作
reducer一定要是一个纯函数,不要在reducer中发生以下操作:
- 修改传入参数
- 调用非纯函数
- 执行有副作用的操作
纯函数:函数的输出结果只跟传入的参数有关,只要参数不变,输出的结果永远不会改变
返回值的操作:不能修改原有的state,可以使用Object.assign({}, state, {newProperty})
和...(展开运算符)
来处理返回结果;遇到无法识别的action时要返回旧的state
拆分reducer:当reducer变得非常复杂时可以将其按照功能拆分,多个reducer通过combineReducers函数来合并或者通过function包装,例如
// todoReducer
const todoState = [
'test',
'code',
'submit',
]
function todoReducer(state = todoState, action) {
switch(action.type) {
case 'ADD_ITEM':
let newState = JSON.parse(JSON.stringify(state))
newState.push(action.value)
return newState
default:
return state
}
}
// roleReducer
function roleReducer(state = 'SHOW_ALL', action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
// index
import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ todoReducer, roleReducer })
let store = createStore(reducer)
// 或者
export default function todoApp(state = {}, action) {
return {
todoReducer: todoReducer(state.todoReducer, action),
roleReducer: roleReducer(state.roleReducer, action)
}
}
Store
redux中只有一个store,是负责将action和state联系起来的容器,提供了更新state的方法dispatch()
和获取state的方法getState()
,通过subscribe()
注册监听器以及销毁监听器
暴露store:
在store文件中引入redux中的createStore方法,引入reducers,然后暴露store
import {createStore} from 'redux'
import reducer from './reducer'
let store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__
&& window.__REDUX_DEVTOOLS_EXTENSION__())
export default store
createStore()的第二个参数可选,填入这段代码可以开启redux devtools进行调试
订阅store以及获取state:
使用store.getState()可以获取到store中的state,在componentDidMount生命周期中添加订阅
constructor(props) {
super(props);
this.state = {
...store.getState(),
}
// 也可以在这里注册
// store.subscribe(() => {
// this.setState(store.getState())
// })
}
componentDidMount() {
store.subscribe(this.storeChange)
}
storeChange = () => {
this.setState(store.getState())
}
subscribe()的参数是一个回调函数,当store中数据发生改变时可以触发方法
更新state:
使用store.dispatch()方法,传入action来更新state
addItem = () => {
if (this.state.input) {
const action = {
type: 'ADD_ITEM',
value: this.state.input
}
store.dispatch(action)
this.setState({
input: ''
})
}
}