Redux 状态管理
Redux
是一个独立的数据管理器,可以运行于不同的环境下,也同样支持别的开发框架(Vue
)。
建议在数据量较大的时候使用。
核心关键
核心概念
state
:
仓库中的初始数据 只读reducer
:
函数 类似仓库管理员,创建仓库时作为形参传入store
:
仓库存放数据,调用方法
下载安装
npm install --save redux
引入使用
// 引入 redux
import { createStore } from 'redux';
// 纯函数 存放原始的 state 数据
// state,action 均为自定义的形参
// state 为传入的初始数据
// action 为修改的值
function reducer(state={ },action){
// 必须写 return 返回数据
return state
}
// 创建仓库引入 纯函数
let store = createStore(reducer);
仓库中的方法
-
getState( )
获取数据console.log(store.getState())
-
dispatch( )
发起一次修改,同步执行(立即执行)
type
为必填项,不可省略,参考git
提交store.dispatch({ type:"change_name", //必填项,自定义字符串 name:"Mr_Qin" }) // 想要实现修改 必须在纯函数中进行判断处理 function reducer(state = { name:"秦兟", age:24 },action){ switch(action.type){ // action.type 满足条件时 执行对应的数据修改 case "change_name": return { ...state, name:action.name } case "change_age": return { ...state, age:action.age } } // 必须返回 return return state; }
-
subscribe( )
监听状态修改
先监听然后修改才会触发回调函数store.subscribe(()=>{ console.log(store.getState()) })
-
replaceReducer( )
替换掉reducer
函数,实际很少使用
拆分仓库 - 实现数据分组
拆分的可行性
store
仓库本身是无法拆分的,这是内部机制决定的
想要实现数据的拆分就只能是拆分仓库管理员,即纯函数reducer
实现函数内部调用函数,即总代理与二级代理的关系,层层管理
- 原代码
import { createStore } from 'redux';
function reducer(state={
index:{info:"首页"},
list:{info:"列表"},
message:{}
},action){
switch(action.type){
case "index_edit_info":
return {
...state,
index:action.index.name
}
}
return store
}
let store = createStore(reducer);
store.subscribe(()=>{
console.log(store.getState())
})
store.dispatch({
type:"index_edit_info",
info:"index下的数据"
})
- 现代码
import { createStore } from 'redux'
function index(state={info:"首页"},action){
switch(action.type){
case "index_edit_info":
return {
...state,
index:action.info
}
}
return state
}
function list(state={info:"列表"},action){
switch(action.type){
case "list_edit_info":
return {
...state,
list:action.info
}
}
return state
}
// 这里是总控制 总管理员
function reducer(state={},action){
return{
// 这里调用 分层的函数,将数据传递进去
// index / list 实际上就是修改数据时返回的值
index:index(state.index,action),
list:list(state.list,action)
}
}
let store = createStore(reducer);
store.subscribe(()=>{
console.log(store.getState())
})
store.dispatch({
type:"index_edit_info",
info:"index下的数据"
})
store.dispatch({
type:"list_edit_info",
info:"list下的一个列表"
})
优化合并
代替reducer
函数的存在
传入一个对象,这个对象中的属性,就是要合并的 reducer
对象的属性名,要和函数名保持一致
import { combineReducers } from 'redux';
// ...
let reducer = combineReducers({
index,
list
})
//-----------------替代函数---------------------
function reducer(state={},action){
return{
index:index(state.index,action),
list:list(state.list,action)
}
}
store
仓库的使用
借用react-redux
实现仓库的使用
- 下载
npm i react-redux
- 引入
import { Provider } from 'react-redux'
- 注入仓库
ReactDOM.render( // 引入 包裹文件 并且将仓库 导入 // 路由 建议放在最外层 不强制要求 <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
store
仓库准备
- 文件摆放
创建一个store
文件夹作为仓库,内部的index
作为入口文件(总管理)
index
文件内容
负责处理多个纯函数(管理下级管理员)import { createStore, combineReducers } from "redux"; // combineReducers 合并管理 import data from "./reducer"; export default createStore(combineReducers({data}));
reducer
文件内容
这里存放的是数据function data(state={ name:'危险', age:"for ever" },action){ switch (action.type) { case "Inner_name": return{ ...state, name:action.name } } return state } export default data;
通过connect
实现,组件中使用仓库数据
- 原理
在哪个组件中需要使用 redux 中的数据,在哪个组件中调用connect(state的处理函数)(组件)
将数据传递给指定的组件state的处理函数
(state,props)=>{ // props 可选参数 return 要传给组件的数据 }
- 实例
将store
中的数据传递给inner
组件,并导出export default connect((state,props)=>{ // console.log(state) return state.data })(InnerPage);
通过hooks
优化对store
的操作
- 引入
import { useSelector, useStore, useDispatch } from "react-redux";
- 使用
// 获取 state 状态(数据) 通过回调函数的返回值,来获取 state let {name,age} = useSelector((state)=>{ return state.data }); // 发起一次提交 即 获取仓库中的dispatch() 方法 let dispatch = useDispatch(); // 获取整体仓库 let store = useStore()
通过redux-thunk
对store
进行异步操作
实际上就是允许,在修改数据时,传入函数;在函数内部进行操作
- 下载安装
npm i redux-thunk
- 引入使用
不能直接使用该依赖,需要有redux
中的applyMiddleware
作为中间的媒介来加载使用
使用时,需要传入到createStore( )
方法中import { createStore, combineReducers,applyMiddleware } from "redux"; import data from "./reducer"; import thunk from "redux-thunk" export default createStore(combineReducers({data}),applyMiddleware(thunk));
- 修改数据的操作
{/* dispatch(function(dispatch,getstate){ 进行逻辑操作 }) */} <button onClick={()=>{ dispatch(function(dispatch,getstate){ setTimeout(()=>{ dispatch({ type:"Inner_name", name:'谨慎' }) },2000) console.log(getstate) }) }}>点击</button>