🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 状态管理--redux 单向数据流、 非父子组件的通信 一个组件的状态有两种方式改变:父组件的 props 改变了,这个组件也会重新渲染;自身的 state 可以通过this.setstate方法改变。 子组件共享状态,当某个子组件改变了,提升到父组件,那么所有的子组件都会重新渲染。 > Redux是将整个应用状态只存储到store,唯一状态树store tree, > > 组件可以派发(dispatch)行为(action)给store,而不是直接通知其他组件,组件内部通过订阅**store**中的状态**state**来刷新自己的视图。 > > store传入state和action给reducers,store从reducers得到新状态,Reducer是一个纯函数,state的计算过程,函数返回的结果必须由参数state和action决定,且不产生任何副作用也不能修改state和action对象 Redux三大原则:唯一数据源、保持只读状态、数据改变只能通过纯函数来执行 store就是保存数据的地方;state就是store里面存储的数据; Action是一个对象,type属性--表示Action的名称;store.dispatch( )是view发出Action的唯一办法 ```js import {createStore} from 'redux' const store=createStore(fn); const state=store.getState() const action={ type:'ADD_TODO', payload:'redux原理' } store.dispatch({ type:'ADD_TODO', payload:'redux原理'}) //store.dispatch(action) const reducer =(state,action)=>{ switch(action.type){ case ADD_TODO: return newstate; default return state } } ``` ## **setState** 调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。 ```js this.setState({ key1: newState1, key2: newState2, ...}, callback) // 第二个参数是 state 更新完成后的回调函数 ``` **setState和replaceState的区别** > replaceState只会保留nextState中状态,原state不在nextState中的状态都会被删除; > > setState 是修改其中的部分状态,相当于 Object.assign,只是覆盖,不会减少原来的状态。而replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象。 组件的**getDefaultProps函数**,对属性设置默认值 ## **redux源码** ```js let createStore = (reducer) => { let state; let listeners = []; // 存放所有的监听函数 let getState = () => state; // 获取状态对象 let dispath = (action) => { // 提供一个方法供外部调用派发action state = reducer(state, action); // 调用管理员reducer得到新的state listeners.forEach((l) => l()) // 执行所有的监听函数 } // 订阅状态变化事件,当状态改变发生之后执行监听函数 let subscribe = (listener) => { listeners.push(listener); } dispath(); return { getState, dispath, subscribe } } let combineReducers=(renducers)=>{ // 传入renducers管理组,返回一个renducer return function(state={},action={}){ let newState={}; for(var attr in renducers){ newState[attr]=renducers[attr](state[attr],action) } return newState; } } export {createStore,combineReducers}; ``` ## **异步请求** 现在有异步请求,但变更redux过程都是同步,因此在store.dispatch的之后,到达reducer之前进行异步操作 ```js store.dispatch = function(prevAction) async{ // 中间件原理--给store.dispatch再包裹一层 console.log("发请求啦"); const list = await getList(); // 异步操作执行完成之后才派发action const newAction={type: prevAction.type, payload:list} //把list放到action里面 store.dispatch(newAction); }; ``` redux 常见的中间件有redux-thunx、redux-promise、redux-saga, redux应用中间件如下 ```js import { applyMiddleware, createStore } from 'redux' import myMiddleware from './myMiddleware' const store = createStore(reducer, applyMiddleware(myMiddleware)) ``` - 通知变更 变更了 state-->将变更通知给 view 了。store.subscribe(listener)方法传入一个listener,listener可以是this.setState(xxx),每当 redux 里面的state改变了,通过store.subscribe(listener)页面也会重新渲染。每个页面都得手动去store.subscribe(listener)。