React(六) —— redux
🧁个人主页:个人主页
✌支持我 :点赞👍收藏🌼关注🧡
文章目录
⛳Redux
redux最主要是用作应用状态的管理。简言之,Redux用一个单独的常量状态树(state对象)保存这一整个应用的状态,这个对象不能直接被改变。当一些数据变化了,一个新的对象就会被创建(使用actions和reducers)这样就可以进行数据追踪。
🍆redux定义
Redux 是一个使用叫做“action”的事件来管理和更新应用状态的模式和工具库。它以集中式Store(centralized store)的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
💐redux使用原则
🔎🔎🔎
- state以单一对象存储在store对象中
- state只读(每次都返回一个新的对象)
- 使用纯函数reducer执行state更新
🍰redux使用场景
🏸🏸🏸
- 同一个state需要在多个Component中共享
- 需要操作一些全局性的常驻Component,如Tooltips等
- 太多props需要在组件树中传递,其中大部分只是为了传给子组件
- 业务太复杂导致Component文件太大,可以考虑将业务逻辑拆出来放到Reducer中
🧊redux工作流程
📢📢📢
- 组件通过dispatch方法触发Action(type+payload载荷)
- Store接收Action并将Action分发给Reducer
- Reducer根据Action类型对状态进行更改并将更改后的状态返回给Store
- 组件订阅了Store中的状态,Store中的状态更新会同步到组件
🥫redux基本
创建store
redux文件夹下的store.js
//1.引入redux,
//2.createStore(reducer)
import {createStore} from 'redux'
const reducer = (preState,action)=>{return prevState
}
const store = createStore(reducer);
export default store
定义改变数据的actions,并在renducer函数中对对应的action作出不同的操作
//store.js 第二个参数为操作的actions
const reducer = (prevState={show:true,//...初始状态值
},action)=>{console.log(action);let newStare = {...prevState}switch(action.type){case 'hide-tabbar':newStare.show = falseconsole.log(newStare.show);return newStare.showcase 'show-tabbar':newStare.show = trueconsole.log(newStare.show);return newStare.showdefault:return prevState}
}
离开或到达Detail页面,触发相应的actions
//Detail.js
import {show,hide} from '../../redux/actionCreator/TabbarActionCreator'useEffect(()=>{//store.dispatch 通知store.dispatch(hide())return()=>{// console.log('destroy');store.dispatch(show())}},[])
.............................................
//actionCreator文件夹下TabbarActionCreator.js
function hide(){return {type:'hide-tabbar'}
}
function show(){return {type:'show-tabbar',//必须有type值//payload:'需要传的值'}
}
export {show,hide}
订阅store,更新状态到页面上
//App.js中
state = {isShow:store.getState()}//store.subcribe 订阅componentDidMount(){store.subscribe(()=>{console.log('app中订阅',store.getState());this.setState({isShow:store.getState().show})})}//store.subcreibe 订阅render() {return (<div><MRouter>{this.state.isShow && <Tabbar></Tabbar>}</MRouter></div>)
}
获得store中的状态,根据状态的不同来控制Tabbar的显示或隐藏
🍸补充(actioncreator)
action creator是一个函数,用于生成一个action对象,他接受一个或多个参数(任何类型的数据),但是必须在action对象中有一个type属性:描述操作的类型。action creator函数返回一个对象,该对象是一个action,这个action对象包含了描述操作的数据
function addTodo(text){return{type:'add_todo'}
}
..............................
store.dispatch(addTodo())
上述:addTodo是一个action creator函数,它接受一个text参数并返回一个包含type和text属性的action对象。在Redux中,我们可以使用dispatch函数将这个action对象发送到store中,以便更新store状态。
🍫redux核心
-
getState:获取状态
store.getState()
-
subscribe:订阅状态
store.subscribe(()=>{})
-
dispatch:触发Action
store.dispatch({type:'description...'})
reducer合并
🚀如果不同的action所处理的属性之间没有联系,我们可以把Reducer函数拆分。不同的函数负责处理不同属性,最终把他们合并成一个大的Reducer,并且抛出在store内的文件中引入。
redux文件夹下CityReducer.js
创建多个reducer,分别管理不同的数据
const CityReducer = (prevState={cityName:'北京'
},action)=>{let newStare = {...prevState}switch(action.type){case 'change-city':newStare.cityName = action.payloadreturn newStaredefault:return prevState}
}
export default CityReducer
store.js
使用combinReducers方法合并多个Reducer。combinReducers方法可以吧多个reducer合并成一个reducer,以便在创建store实例时使用
import {combineReducers, createStore} from 'redux'
import CityReducer from './reducers/CityReducer';
import TabbarReducer from './reducers/TabbarReducer';
const reducer = combineReducers({CityReducer,TabbarReducer
})
const store = createStore(reducer);
export default store
redux中间件
在redux里,action仅仅是携带了数据的普通js对象,action creator返回的值是这个action类型的对象,然后通过store.dispatch()进行分发。同步的情况下一切都很完美,但是reducer无法处理异步的情况。
那么我们就需要action和reducer中间架起一座桥梁来处理异步。这就是middleware
redux-thunk
作用
🚒让我们的action创建函数不仅仅返回一个action对象,也可以返回一个函数,这个函数会接受dispatch和getState两个参数,我们可以在函数内部进行 异步操作 ,然后再通过dispatch发出一个新的action对象,来更新应用的状态
安装redux-thunk
npm i --save react-thunk
引入
import {applyMiddleware, combineReducers, createStore} from 'redux'
import reactThunk from 'redux-thunk'
const reducer = combineReducers({.....
})
const store = createStore(reducer,applyMiddleware(reactThunk));
export default store
使用方法
import getCinemsListAction from '../redux/actionCreator/getCinemsListAction'
store.dispatch(getCinemsListAction())
...............................
import axios from "axios"
function getCinemasListAction(){return(dispatch)=>{axios({........}).then(res=>{console.log(res.data.data.cinemas);dispatch({type:'change-list',payload:res.data.data.cinemas})})}
}
export default getCinemasListAction
注意:
当我们使用react-thunk中间件时,他会判断action是否为函数,如果是函数就执行这个函数,并在函数内部发出一个新的action对象,若不是则按照正常进行
取消订阅
//订阅var unsubcribe=store.subscribe(()=>{})return ()=>{//取消订阅unsubcribe()}},[])
redux-promise
安装redux-promise
npm i redux-promise
引入
import {applyMiddleware, combineReducers, createStore} from 'redux'
import reactThunk from 'redux-thunk'
import reactPromise from 'redux-promise'
const reducer = combineReducers({....
})
const store = createStore(reducer,applyMiddleware(reactThunk,reactPromise));
export default store
使用方法
import getCinemsListAction from '../redux/actionCreator/getCinemsListAction'
store.dispatch(getCinemsListAction())
...............................
import axios from "axios"
async function getCinemasListAction(){var list = await axios({......}).then(res=>{return{type:'change-list',payload://res.data.data.cinemas}})return list}
export default getCinemasListAction