使用Redux效果如下图:
Redux工作流程如下:
项目开发表中目录结构如下:
redux三个基本原则
- 项目中的
store
必须是唯一的 - 只有
store
能改变数据内容 Reducer
必须是纯函数(纯函数是指给定固定的输入,就一定会有固定的输出,而且不会有任何副作用的产生)
redux主要API接口
createStore
创建一个 store 对象store.dispatch()
将 action 传递到store中store.getState()
获取 store 中的数据store.subscribe()
只要 store 中的数据发生变化时,就会执行
TodoList案例部分核心代码
- index.js(store入口文件)
import {createStore} from 'redux';
import reducer from './reducer'
//获取到数据
const store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
- reducer.js(可以看作的是对数据的处理)
// 注意:Reducer必须是纯函数,并且它并没有修改 state 中的数据
// 纯函数指给定固定的输入,就一定有固定的输出,而且不会有任何副作用
//导入action类型
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DEL_TODO_ITEM} from './actionTypes.js';
const defaultData = {
inputValue:'',
list:[]
};
/*
state表示上一次传递过来的数据,action表示用户传递过来的action
reducer 可以接收state的数据,但不可修改state
*/
export default (state = defaultData,action) => {
// console.log(state,action);
//输入框数据发生变化的时候
if(action.type === CHANGE_INPUT_VALUE){
const newState = JSON.parse(JSON.stringify(state)); //深度复制
newState.inputValue = action.value;
/*
newState.inputValue = new Date();
这样处理之后就不在是一个纯函数了,因为其随时间的变化而变化
*/
return newState;
}
//点击提交按钮
if(action.type === ADD_TODO_ITEM){
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
console.log(newState);
return newState;
}
//删除点击当前的item
if(action.type === DEL_TODO_ITEM){
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index,1);
return newState;
}
return state; //将数据返回
}
- actionTypes.js(统一规范action的类型值)
// 将action的类型统一管理,方便后期排错
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DEL_TODO_ITEM = 'del_todo_item';
- actionCreator.js(将action进行封装)
// 将action的类型统一管理,方便后期拍错
// 将action进行统一的封装
//导入action类型
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DEL_TODO_ITEM} from './actionTypes.js';
//es6高级语法,直接返回一个对象
export const getInputChangeAction = (value) => ({
type:CHANGE_INPUT_VALUE,
value,
})
export const getAddItemAction = () => ({
type:ADD_TODO_ITEM,
})
export const getDelItemAction = (index) => ({
type:DEL_TODO_ITEM,
index
})
- 组件中使用
store
和action
部分核心代码
//直接来使用actionCreator封装的action方法
import {getInputChangeAction,getAddItemAction,getDelItemAction} from './store/actionCreator.js'
//使用store
import store from "./store/index"
constructor(props){
super(props);
this.handleStoreChange = this.handleStoreChange.bind(this);
store.subscribe(this.handleStoreChange); //使得store中的数据时刻更新
}
//输入框发生改变的时候
handleInputChange(e){
const action = getInputChangeAction(e.target.value); //调用封装的action方法
store.dispatch(action);
}
//点击提交 的时候
handleClick(){
const action = getAddItemAction();
store.dispatch(action);
}
//store中数据发生变化的时候
handleStoreChange(){
// console.log("store change");
this.setState(store.getState());
}
详细请参考: https://github.com/zlqGitHub/HTML-CSS-JS/tree/master/JS框架/React框架/my-app