由于之前redux创建store太繁琐,样板代码太多等人,redux官方推出了更简易的、有想法的、强劲的、高效的Redux-Toolkit,使其使用起来更为简单便捷,简称为RTK,也是现官方推荐的编写redux逻辑的方法。
安装包依赖:
npm @reduxjs/toolkit react-redux
配置Redux文件:
在src创建store文件夹,store文件用来配置状态并导出,reducer文件使用Redux-Toolkit的切片对象生成actions以及reducer,然后导出
reducer文件中引入reduxjs/toolkit依赖项,然后配置初始状态,也就是我们需要管理的共享初始状态
import { createSlice } from '@reduxjs/toolkit';
// 初始状态
const initState = {
count: 1,
users:[
{
name:"redux-tiilkit",
pass:123
}
],
infor:{
infor_num:20,
infor_type:"cosplay",
infor_name:"GTA5"
}
}
reduxjs/toolkit的createSlice故切片对象,会帮我们自动生成action关并联对应reducer
// 创建redux切片对象
export const setInitState = createSlice({
name:"appState", // 切片名称 用来标识redux
initialState:initState, // 需要管理的状态
reducers:{ // 配置reducer 用以更新的状态
countAdd(state){
state.count++;
},
setCount(state,action){
state.count = action.payload;
},
addUsers(state,{payload}){
state.users.push(payload)
},
setInfor(state,{payload}){
let {num,type,name} = payload;
state.infor.infor_num = num;
state.infor.infor_type = type;
state.infor.infor_name = name;
}
}
})
然后导出action以及reducer
// 导出状态
export const {countAdd,setCount,addUser,setInfor} = setInitState.actions;
// 导出reducer
export const SetInitState = setInitState.reducer;
然后配置store文件,也可以在该文件进行数据持久化等配置,然后导出
import { configureStore } from "@reduxjs/toolkit";
import { SetInitState } from "./reducer";
const store = configureStore({
reducer:{
SetInitState,
}
})
export default store;
接下来在最顶层组件引入刚刚导出的store,用Provider包裹并将store注入,以供全局使用,一般为src文件夹下的index.js文件,这里我个人将它放在了路由组件的下一层
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom';
import store from './store/store';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
);
在Section这个组件中获取到count的状态值然后展示在页面,在ReduxTest组件中改变count的状态,使用redux共分享状态
需要拿到更新后状态-Section组件:
// 引入Redux-hook
import { useSelector } from 'react-redux';
// 拿到redux定义的初始状态
const {count} = useSelector(state => state.SetInitState);
// 在组件中展示
<div style={{background:"white"}}>
<p>Sectiont页面Redux-Count:{count}</p>
<br />
<div>Sectiont页面Redux-Users:
{users.map(item => (
<div key={item.name} style={{ width: "100%", border: "1px dashed blue", margin: "5px 0", padding: "5px 20px", boxSizing: "border-box" }}>
<p>name:{item.name}</p>
<p>pass:{item.pass}</p>
</div>
))}
</div>
<br />
<div>ReduxTest页面Redux-Infor状态:<br />
<p>infor_num:{infor.infor_num}</p>
<p>infor_num:{infor.infor_type}</p>
<p>infor_num:{infor.infor_name}</p>
</div>
</div>
更新状态组件-ReduxTest组件:
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { addUsers, countAdd, setInfor } from '../../store/reducer'
export default function ReduxTest() {
const { count, users, infor } = useSelector(state => state.SetInitState);
const dispatch = useDispatch();
// 改变count状态
const clickCount = () => {
dispatch(countAdd());
}
// 改变users状态
const clickUser = () => {
dispatch(addUsers({
"name": "newUser",
"pass": 123
}));
}
// 改变infor状态
const clickInfor = () => {
dispatch(setInfor({
"num":666,
"type":"newType",
"name":"newName"
}));
}
return (
<div>
<div style={{ background: "white" }}>
<p>ReduxTest页面Redux-Count:{count}</p>
<br />
<div>ReduxTest页面Redux-Users:
{users.map(item => (
<div key={item.name} style={{ width: "100%", border: "1px dashed blue", margin: "5px 0", padding: "5px 20px", boxSizing: "border-box" }}>
<p>name:{item.name}</p>
<p>pass:{item.pass}</p>
</div>
))}
</div>
<br />
<div>ReduxTest页面Redux-Infor状态:<br />
<p>infor_num:{infor.infor_num}</p>
<p>infor_num:{infor.infor_type}</p>
<p>infor_num:{infor.infor_name}</p>
</div>
</div>
<br />
<p><button onClick={clickCount}>ReduxTest组件,点击count+1</button></p>
<br />
<p><button onClick={clickUser}>ReduxTest组件,点击添加user</button></p>
<br />
<p><button onClick={clickInfor}>ReduxTest组件,点击改变infor</button></p>
</div>
)
}
改变前:
依次点击按钮,改变后:
就这么简单的实现全局组件共享,比原来的redux方便太多了。
over!over!