Redux是什么?
- 是专于状态管理的库
- 专于状态管理和react解耦
- 单一状态,单项数据流
- 核心概念 store state action reducer
Redux工作流
react 要改变store里的数据,先要开发一个action,action会通过store.dispatch(action)传递给store;
store会把之前的state和action转发给reducer;
reducer是一个函数,接收到state和action,做一些处理之后,会返回一个新的state给store;
store用新的state替换掉之前store里的state;
store改变之后,react组件会感知store发生改变,这是组件从store里重新取数据,更新组件内容,页面就跟着发生变化了。
把redux工作流程必做借书过程的话,react组件是“借书的人”,store是“图书管理员”,action 是“借书的人和图书管理员说的话”,reducer是“图书管理员的查书手册”。当借书者(react组件)想要借一本书时,会和图书管理员(store)说一句话(action),这句话有固定格式,必须是对象或者函数,包含type和value,图书管理员(store)听到话后回去查手册(reducer),手册(reducer)会根据之前的数据(state)和这句话(action),告诉图书管理员(store)现在的数据是什么,管理员(store)拿到现在的数据替换老数据。
redux三项原则
store唯一的
只有store能改变自己的内容
reducer必须是纯函数(给定固定的输入,就会有固定的输出,而且不会有副作用)
常用API
createStore :创建store
const store = createStore(reducer, enhancer);
store.dispatch :派发action
const action=getInitListAction(); store.dispatch(action);
store.getState :获取store里所有内容
constructor(props){ super(props); this.state=store.getState(); }
store.subscribe :监控store里的state是否改变
constructor(props){ super(props); this.state=store.getState(); this.listenerStoreChange=this.listenerStoreChange.bind(this); store.subscribe(this.listenerStoreChange); }
文件目录说明
actionType.js
export const INPUT_CHANGE = 'InputChange'; export const BTN_CLICK='BtnClick' export const ITEM_CLICK='ItemClick' export const INIT_LIST='InitList' export const GET_INIT_LIST='GetInitList'
actionCreator.js 创建action
import axios from 'axios'; import { INPUT_CHANGE , BTN_CLICK , ITEM_CLICK , INIT_LIST , GET_INIT_LIST} from './actionType'; export const getInputChangAction = (value)=>({ type:INPUT_CHANGE, value }); export const getBtnClickAction = ()=>({ type:BTN_CLICK }); export const getItemClickAction = (index)=>({ type:ITEM_CLICK, index }); export const initListAction = (data)=>({ type:INIT_LIST, data }); export const getInitListAction = ()=>({ type:GET_INIT_LIST });
reducer.js
import { INPUT_CHANGE , BTN_CLICK , ITEM_CLICK , INIT_LIST} from './actionType'; //defaultState设置了仓库的默认数据 const defaultState={ inputValue:'123', list:[1,2] } //reducer 返回的必须是一个函数,函数有两个参数,一个是state上一次的数据,另一个是action //reducer 可以接受state,但是绝不能修改state export default (state=defaultState,action)=>{ if(action.type===INPUT_CHANGE){ const newState=JSON.parse(JSON.stringify(state)); newState.inputValue=action.value; return newState; } if(action.type===BTN_CLICK){ const newState=JSON.parse(JSON.stringify(state)); newState.list.push(newState.inputValue); newState.inputValue='' return newState; } if(action.type===ITEM_CLICK){ const newState=JSON.parse(JSON.stringify(state)); newState.list.splice(action.index, 1) return newState; } if(action.type===INIT_LIST){ const newState=JSON.parse(JSON.stringify(state)); newState.list=action.data return newState; } return state; }
index.js 创建store
import { createStore, applyMiddleware ,compose} from 'redux'; import reducer from './reducer' import createSagaMiddleware from 'redux-saga' import mySaga from './sagas' const sagaMiddleware = createSagaMiddleware(); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose; const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware)); //创建store用redux里的createStore方法 //创建store要把reducer引进来 const store = createStore(reducer, enhancer); sagaMiddleware.run(mySaga) export default store;