是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式,我们强烈建议你使用它。
它包括几个实用程序功能,这些功能可以简化最常见场景下的 Redux 开发,包括配置 store、定义 reducer,不可变的更新逻辑、甚至可以立即创建整个状态的 “切片 slice”,而无需手动编写任何 action creator 或者 action type。它还自带了一些最常用的 Redux 插件,例如用于异步逻辑 Redux Thunk,用于编写选择器 selector 的函数 Reselect ,你都可以立刻使用。
-
本质:redex和redux-thunk进行封装
-
核心:
-
仓库,存放全局数据
-
reducer:定义修改该数据的行为(方法)的
-
actions:行为
# NPM npm install @reduxjs/toolkit # Yarn yarn add @reduxjs/toolkit
Redux Toolkit API文档:
-
configureStore:
-
作用:创建仓库,返回值就是一个仓库
-
语法:let store = configureStore({各自的reducer}) ; // 合并reducer
代码实现:在store文件夹创建一个index.js文件,在里面引入各自的reduce,集中关联 reducer
-
import {configureStore,createSlice} from '@reduxjs/toolkit'
import meReducer from './modules/MeState'
import cartReducer from './modules/CartState'
import LimitReducer from './modules/LimitState'
//configureStore =》语法
//返回值 =》就是仓库
//configureStore({各自的reducer}) =>合并reducer
//创建仓库
const store = configureStore({
reducer: { //模块化对象
me:meReducer,
cart:cartReducer,
limit:LimitReducer
}
})
console.log(store);
// export default store //创建仓库 =》让仓库和react 进行关联 react-redux
export default store
-
createSlice:
-
作用:存放仓库中的数据,和定义仓库的行为(创建各自的reducer)
-
语法:let Mystate= createSlice({ }); // 创建reducer,存放数据initalState,定义行为reducers
-
import {createSlice} from '@reduxjs/toolkit'
// 创建 reducer => 存放仓库数据,和定义仓库的行为
// 作用:createSlice => 创建 各自的reducer
// 语法
// 返回值 = createSlice => 对象
// createSlice({实例属性})
let MeState=createSlice({
name:'me', // 作用域 唯一标识 => 我的模块存放的全局数据
initialState:{
name:'我是小明',
age:20,
num:100,
},
// reducer =》 定义方法修改仓库中的数据
// 相对 vue muations => 定义修改 仓库中的数据
reducers:{
changeName(state,val){ // 第一个参数 就是这个仓库的存放(模板)的数据 第二个参数 就是 调用这个方法传递过来的数据
console.log(val);
// 重新创建仓库数据吗?return {num:最新的数据} =>
state.name=val.payload; // 就是对数据进行更新
},
addAge(state){
state.age+=1;
},
addNum(state,val){
state.num=state.num+val.payload;
}
}
})
console.log(MeState);
// 将行为暴露出去
export let {changeName,addAge,addNum}=MeState.actions // 本质就是将这个方法暴漏出去
export default MeState.reducer
核心:为我们react项目提供的一个组件,两个hooks
组件:Provider 1 作用:在父级组件中提供数据 ,其他的子集组件就可以获取到;
2 在父组件中提供了数据 store;
hooks:
useSelector: 1 作用:在组件中获取仓库中的数据,再通过useState修改数据方法,让数据更新
2 语法:useSelector(state => { return 返回值}) // 返回 在仓库中获取的数据
useDispatch 1 作用:可以获取到更新组件的dispatch,先触发reducer,
2 语法:let dispatch=useDispatch(); dispatch({type:'add'});
1. 安装react-redux
npm i react-redux
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import { Provider } from 'react-redux'; import store from './store'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> <App /> </Provider> );
import './App.css'; // (1)引入 react-redux 中提供的两个方法 import { useSelector,useDispatch } from 'react-redux'; // (2) 在页面(组件中获取数据) import {add,sub,addLIst,subList} from './store/modules/CartState' import { changeName,addNum} from './store/modules/MeState'; function App() { let dispatch=useDispatch(); // (3) 注意我们的行为 => 需要我们暴露处理 => 而这些行为就是reducers中定义的方法 let state =useSelector(store=>store); console.log(state) return ( <div className="App"> <h2> 获取到仓库中的数据{state.me.name}</h2> <h3>CartState {state.cart.num}</h3> <h3>MeState {state.me.num}</h3> {/* 修改仓库中数据 三点核心属性: reducer actions => dispatch(行为) store */} <button onClick={()=>{dispatch(changeName("我不是小明"))}}>修改MeName中的数据</button> <button onClick={()=>{dispatch(add(10))}}>修改CartState仓库中的数据num</button> <button onClick={()=>{dispatch(addNum(10))}}>修改MeState仓库中的数据num</button> </div> ); } export default App;
五、处理仓库中的复杂数据类型
处理方法:就是使用操作复杂数据类型的方法
import {configureStore,createSlice} from '@reduxjs/toolkit'
//创建reducer =>createSlice
let reducerNum = createSlice({
name:'nums',// 空间命名
initialState:{
num:2,
list:[1,2,3,4,5]
},
// 相对于vue mutations =》 定义方法修改 仓库中的数据
reducers:{
//在这里定义的方法 (1)第一个参数 当前reducer 的数据 (2) actions
add(state,data){
console.log(state,data.payload);
// 重新创建仓库数据吗? return {num:最新的数据} =》
state.num = state.num+data.payload // 就是对数据进行更新
},
reduce(state){
state.num = state.num -1
},
// 写的方法寓意化一下
addList(state,data){
state.list.push(data.payload)
},
reduceList(state,data){
state.list.splice(data.payload,1)
}
}
})
//注意 暴露actions
export let {add,reduce,addList,reduceList} = reducerNum.actions //
console.log( reducerNum);
// 创建 store
//configureStore => 创建仓库
// 语法: configureStore({ reducer:{}})
export default configureStore({
reducer:{
//写reducer
reducerNum:reducerNum.reducer
}
})
import {add,reduce,addList,reduceList} from './store/index'
function App() {
let {num,list} = useSelector(store=>store.reducerNum) //{num,list}
let dispatch = useDispatch()
// console.log(store);
return (
<div className="App">
<h2>toolkit</h2>
<h2>{num}</h2>
<button onClick={()=>dispatch(add(2))}>+</button>
<button onClick={()=>dispatch(reduce())}>-</button>
{
list.map((item,index)=>{
return<div key={index} onClick={()=>dispatch(reduceList(index))}>{item}</div>
})
}
<button onClick={()=>dispatch(addList(1000))}>添加list</button>
</div>
);
}
六、处理异步问题
之前在redux中需要引入 第三方插件:react-thunk,而使用了redux Tookit是内置了react-thunk,
// 自己定义异步actions // 1 获取到异步的数据,再触发reducer => 修改仓库中的数据 // 2 定义 actions export function getRouterData(){ // 异步actions // 1 获取到异步的数据 function getData(){ // get需要传参,否则会报错 return axios.get('').then(res=>{ // 获取到的是异步的数据 let routerList=[1,2,3,4,5]; return routerList }) } // 2 再触发 reducer return async (dispatch)=>{ // 返回的处理方法的第一个参数就是 dispatch let data =await getData(); // 获取到异步的数据 dispatch(addRouter(data)) } }
2.需要在reducer 定义方法,然后在组件中操作这个方法
import {createSlice} from '@reduxjs/toolkit';
import axios from 'axios';
let LimitState=createSlice({
name:'limit',
initialState:{
router:[]
},
reducers:{ // 只能处理同步问题的问题
addRouter(state,data){
console.log('获取到异步的路由信息',data);
// router 的数据是后端给的 payload
state.router=data.payload
}
}
})
// 注意 => 暴露两个
// 1 reducers 中的行为 => 那个组件使用直接引入
export let {addRouter}=LimitState.actions;
export default LimitState.reducer;
3. 在组件中触发异步actions,
1. dispatch(异步actions方法的调用),调用的这个是异步actions的方法,然后再通过reduceer修改异步数据
import './App.css'; // (1)引入 react-redux 中提供的两个方法 import { useSelector,useDispatch } from 'react-redux'; // (2) 在页面(组件中获取数据) import { getRouterData } from './store/modules/LimitState'; function App() { let dispatch=useDispatch(); let state =useSelector(store=>store); console.log(state) return ( <div className="App"> <h2> 获取到仓库中的数据{state.limit.router}</h2> <button onClick={()=>dispatch(getRouterData())}>仓库中获取到异步的数据</button> </div> ); } export default App;
浙公网安备 33010602011771号