Redux Toolkit
的出现,让我们进一步释放双手,越来越简单啦!!如果你觉得redux-thunk
不好用的话,官方又给我们推出了一套的新的方案:redux-toolkit
,当你用完后,你会发现,和vue3
的pinia
是多么的相似!!!
redux-toolkit 内部帮我们做了很多内置工作,让我们可以直接修改state,不再需要redux-immutable
和mmutable
,使我们能方便的处理数据了。
实现效果
代码实现
- 安装
bash
npm i redux-toolkit
- store/index.js
js
import { configureStore } from "@reduxjs/toolkit";
import CounterReducer from "./CounterReducer";
export const store = configureStore({
reducer: {
count: CounterReducer,
// other reducers
},
});
export default store;
- CounterReducer.js
js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
counter: 0,
userInfo: {
name: "John Doe",
age: 25,
},
};
export const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
add: (state) => {
state.counter += 1;
console.log("🚀 ~ state:", state.counter);
},
dec: (state) => {
state.counter -= 1;
console.log("🚀 ~ state:", state.counter);
},
changeName: (state, action) => {
console.log("🚀 ~ payload:", action);
state.userInfo.name = action.payload;
},
handleDelayAddByTen1: (state, action) => {
console.log("🚀 ~ action:", action);
state.counter += action.payload;
},
},
});
// async action 2s later
function handleDelayAdd() {
return (dispatch) => {
setTimeout(() => dispatch(add()), 2000);
};
}
// async action 2s later
function handleDelayReduce() {
return (dispatch) => {
setTimeout(() => dispatch(dec()), 2000);
};
}
function handleDelayAddByTen(count) {
return (dispatch) => {
setTimeout(() => dispatch(handleDelayAddByTen1(count)), 2000);
};
}
// export actions,提供给组件调用
export const { add, dec, changeName, handleDelayAddByTen1 } =
counterSlice.actions;
export { handleDelayAdd, handleDelayReduce, handleDelayAddByTen };
// export reducer,提供给store使用
export default counterSlice.reducer;
- DemoB.js
js
import { useSelector, useDispatch } from "react-redux";
import { Button, Space, Divider } from "antd";
import {
add,
dec,
changeName,
handleDelayAdd,
handleDelayReduce,
handleDelayAddByTen,
} from "../../store/CounterReducer";
function DemoB() {
const count = useSelector((state) => state.count.counter);
const userInfo = useSelector((state) => state.count.userInfo);
const dispatch = useDispatch();
return (
<div>
<p>Demo B</p>
<div>
<Space split={<Divider />}>
<span>name: {userInfo.name}</span>
<span>age: {userInfo.age}</span>
<span>count:{count}</span>
</Space>
</div>
<Space>
<Button type="primary" onClick={() => dispatch(add())}>
add count
</Button>
<Button type="primary" danger onClick={() => dispatch(dec())}>
minus count
</Button>
<Button type="primary" onClick={() => dispatch(handleDelayAdd())}>
delay 2s add count
</Button>
<Button
type="primary"
danger
onClick={() => dispatch(handleDelayReduce())}
>
delay 2s minus count
</Button>
<Button
type="primary"
onClick={() => dispatch(handleDelayAddByTen(10))}
>
delay 2s add count by 10
</Button>
<Button
type="dashed"
danger
onClick={() => dispatch(changeName("张学友"))}
>
change name
</Button>
</Space>
</div>
);
}
export default DemoB;
-DemoA.js
js
import { useSelector } from "react-redux";
function DemoA() {
const count = useSelector((state) => state.count.counter);
return <div>{<p> Demo A count: {count}</p>}</div>;
}
export default DemoA;
- index.js
js
import DemoA from "./DemoA";
import DemoB from "./DemoB";
import store from "../../store/index";
import { useEffect, useState } from "react";
import { Divider, Space } from "antd";
import { useSelector } from "react-redux";
function Redux() {
const count = useSelector((state) => state.count.counter);
return (
<div>
Redux parent count:{count}
<Divider />
<Space split={<Divider type="vertical" />}>
<DemoA />
<DemoB />
</Space>
</div>
);
}
export default Redux;
总结
- 这一套下来,简直不要太简单了,同步异步的操作与
redux-thunk
大同小异了,很容易理解。 - 参考redux-toolkit官网地址