一、什么是Redux?
Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。它专门为React.js这门框架设计,但并不是只能用于react,可以用于任何界面库。
那为什么React.js需要这个状态容器管理呢?
首先明确React是什么,根据官方的定义,React仅仅是一个视图层的框架,解决的是数据与模板的渲染问题,但是并没有提供数据的状态管理方案,这在大型项目中是一个非常大的痛点。比如说:
二、Redux设计原则
1、单一数据源
使用redux的程序,所有的state都存储在一个单一的数据源store内部,类似一个巨大的对象树。
2、state只读
state是只读的,外部能改变state的唯一方式是通过触发action来修改
3、使用纯函数进行修改
为了描述action如何改变state,需要编写一些具体的逻辑,这些逻辑写在reducer中。而reducer就是一些纯函数。
纯函数:有固定的参数输入且有固定的return输出,不会存在异步的操作,同时在这个过程中不会修改参数的值。
三、Redux工作流
四、使用redux
// src/store/index.js
import { createStore } from 'redux';
import reducer from './reducer';
//通过createStore创建一个store,把reducer作为参数传入
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()//chrome中激活redux devtools插件
);
export default store;
// src/store/reduce.js
const defaultState = {
inputValue: '',
list: []
}
export default (state = defaultState, action) => {
if(action.type === 'add_item') {
const newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue)
newState.inputValue = ''
return newState
}
return state;
}
// App.js
import React, { Component } from 'react'
import store from './store/index.js'
class App extends Component {
constructor(props) {
super(props);
//从redux拿到state
this.state = store.getState()
//store需要通过一个方法给组件传递newState,并将这个方法传入subscribe函数的参数里面
this.handleStoreChange = this.handleStoreChange.bind(this)
store.subscribe(this.handleStoreChange)
}
render() {
return (
//渲染部分
);
}
handleStoreChange() {
//更新组件状态
this.setState(store.getState())
}
}
export default App;
//在响应点击事件的函数中
handleItemClick(e) {
const action = {
type: 'add_item',
value: e.target.value
}
//由store进行action的分发
store.dispatch(action)
}
五、更科学地编写Action
仔细想想,其实上面编写响应函数里面的action部分其实是有问题,因为当我们输入字符串的时候,一不小心输错了一个字母,无法进行状态的变化,但这个时候reducer识别不了对应的type,也不会报错。这个时候可能调试会浪费非常多的时间。
这时候就需要编写更加规范的action来防止这种事故。
// src/store/actionTypes.js
export const ADD_ITEM = 'add_item'
// src/store/actionCreators.js
import { ADD_ITEM } from "./actionTypes";
export const getAddItemAction = (e) => ({
type: ADD_ITEM
value: e.target.value
})
// src/store/reducer.js
import { ADD_ITEM } from './actionTypes'
const defaultState = {
inputValue: '',
list: []
}
export default (state = defaultState, action) => {
//这里改成ADD_ITEM
if(action.type === ADD_ITEM) {
const newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue)
newState.inputValue = ''
return newState
}
return state;
}
然后,在App.js中,
//首先引入Action
import { getAddItemAction } from './store/actionCreators'
//修改响应函数
handleItemClick(e) {
const action = getAddItemAction(e)
store.dispatch(action)
}
这样的编写方式虽然引入了actionTypes和actionCreators,操作更加 麻烦,但是更能应对大型复杂项目的action管理,实际上提高了开发维护的效率。
这是对redux初步的小结,希望对大家有所帮助。