一、什么是Redux?
Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。它专门为React.js这门框架设计,但并不是只能用于react,可以用于任何界面库。
那为什么React.js需要这个状态容器管理呢?
首先明确React是什么,根据官方的定义,React仅仅是一个视图层的框架,解决的是数据与模板的渲染问题,但是并没有提供数据的状态管理方案,这在大型项目中是一个非常大的痛点。比如说:
凡是复杂一些的应用都会有这样组件树的结构,那么非父子组件如何传递数据呢?比如标记上蓝色的组件与右下角的组件进行数据传递,如果仅仅用react组件的父子传值方法,那么需要先传递给父组件,然后由父组件传给上一级的父组件,然后再向下面的子组件传递......明明只是两个组件的交互,居然要 用如此复杂的操作,是不是让人非常沮丧呢?如果项目稍微复杂,即使可以开发,但也变得不可维护。因此Redux应运而生。让Redux统一管理数据,任何组件对数据的操作,都交给redux管理,这样就大大提高了开发和维护的效率。二、Redux设计原则
1、单一数据源
使用redux的程序,所有的state都存储在一个单一的数据源store内部,类似一个巨大的对象树。
2、state只读
state是只读的,外部能改变state的唯一方式是通过触发action来修改
3、使用纯函数进行修改
为了描述action如何改变state,需要编写一些具体的逻辑,这些逻辑写在reducer中。而reducer就是一些纯函数。
纯函数:有固定的参数输入且有固定的return输出,不会存在异步的操作,同时在这个过程中不会修改参数的值。
三、Redux工作流
也许第一次看不是很明白,没有关系,可以用图书馆借书的例子做一个类比: 一图胜千言,其实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初步的小结,希望对大家有所帮助。
转载于:https://juejin.im/post/5d0856e951882559ed71d692