需要安装以下
yarn add @reduxjs/toolkit react-redux
# or
npm i -D @reduxjs/toolkit react-redux
创建src/store/features
创建index.ts
在src/store
目录下
// 创建仓库
import { configureStore } from '@reduxjs/toolkit';
/**
* 子仓库
* features:也可以命名为 module
*/
import counter from '@/store/features/counter';
import home from '@/store/features/home';
/** 初始化仓库 */
const store = configureStore({
reducer: { counter, home },
});
// 当初仓库
export default store;
如果需要编写异步函数,需要使用createAsyncThunk
创建
extraReducers
下有三种状态
pending
:正在发送fulfilled
:获取成功rejected
:失败这种写法是为了往后兼容
home.ts
位于src/store/features
下
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { getBanners } from '@/api/home';
/** 获取导航栏 */
export const fetchHomeMultidataAction = createAsyncThunk('fetch/homeBannersData', async () => {
const result = await getBanners();
return result.data;
});
const homeSlice = createSlice({
name: 'home',
initialState: {
banners: [],
recommends: [],
},
reducers: {
/** 获取板块 */
changeBanners(state, { payload }) {
state.banners = payload;
},
/** 获取评论 */
changeRecommends(state, { payload }) {
state.recommends = payload;
},
},
extraReducers: (builder: any) => {
/** 正在发送 */
builder.addCase(fetchHomeMultidataAction.pending, (state: any, { payload }: any) => {
console.log('处理正在进行中的逻辑');
});
/** 请求成功 */
builder.addCase(fetchHomeMultidataAction.fulfilled, (state: any, { payload }: any) => {
console.log('处理成功的结果,并将结果赋值');
state.banners = payload;
});
/** 请求失败 */
builder.addCase(fetchHomeMultidataAction.rejected, (state: any, { payload }: any) => {
console.log('处理失败的结果');
});
},
});
export const { changeBanners, changeRecommends } = homeSlice.actions;
export default homeSlice.reducer;
需要注意的是,这种写法将在v2
版本中移出
home.ts
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { getBanners } from '@/api/home';
/** 获取导航栏 */
export const fetchHomeMultidataAction = createAsyncThunk('fetch/homeBannersData', async () => {
const result = await getBanners();
return result.data;
});
const homeSlice = createSlice({
name: 'home',
initialState: {
banners: [],
recommends: [],
},
// 普通修改
reducers: {
/** 获取板块 */
changeBanners(state, action) {
// 未解构出来的是action,里面有 payload
state.banners = action.payload;
},
/** 获取评论 */
changeRecommends(state, { payload }) {
state.recommends = payload;
},
},
// 异步修改 -- 这种写法将被弃用
extraReducers: {
/** 正在发送 */
[fetchHomeMultidataAction.pending.toString()](state: any, action: any) {
console.log('处理正在进行中的逻辑');
},
/** 完成 */
[fetchHomeMultidataAction.fulfilled.toString()](state: any, { payload }) {
console.log('处理成功的结果,并将结果赋值');
state.banners = payload;
},
/** 失败 */
[fetchHomeMultidataAction.rejected.toString()](state: any, action: any) {
console.log('处理失败的结果');
},
},
});
export const { changeBanners, changeRecommends } = homeSlice.actions;
export default homeSlice.reducer;
import { connect } from 'react-redux';
import { Component } from 'react';
import { addNumber, subNumber } from '@/store/features/counter';
import { fetchHomeMultidataAction } from '@/store/features/home';
interface Props {
counter: number;
subNumber: Function;
addNumber: Function;
fetchHomeMultidataAction: Function;
banners: [];
recommends: [];
}
export class Profile extends Component<Props> {
/** 当组件刚挂载时,派发请求 */
componentDidMount() {
this.props.fetchHomeMultidataAction();
}
render() {
const { counter, banners, recommends } = this.props;
return (
<div>
<div>
<h3>Profile counter {counter}</h3>
<button onClick={() => this.props.addNumber(6)}>+6</button>
<button onClick={() => this.props.subNumber(6)}>-6</button>
</div>
<ul>
{banners.map((item: any) => {
return <li key={item.boardId}>{item.boardName}</li>;
})}
</ul>
<ul>
{recommends.map(item => (
<li>{item}</li>
))}
</ul>
</div>
);
}
}
/** 用于赋值, */
const mapStateToProps = (state: any) => ({
counter: state.counter.counter,
banners: state.home.banners,
recommends: state.home.recommends,
});
// 用于派发请求,由于本身有 dispatch 所以不用使用 store.dispatch
const mapDispatchToProps = (dispatch: any) => ({
addNumber(num: number) {
dispatch(addNumber(num));
},
subNumber(num: number) {
dispatch(subNumber(num));
},
/** 这个是异步请求 */
fetchHomeMultidataAction() {
dispatch(fetchHomeMultidataAction());
},
});
// 用于连接组件和仓库进行
export default connect(mapStateToProps, mapDispatchToProps)(Profile);
函数组件和类组件同理
import { useEffect } from 'react';
import { connect } from 'react-redux';
import { addNumber, subNumber } from '@/store/features/counter';
import { fetchHomeMultidataAction } from '@/store/features/home';
interface Props {
counter: number;
subNumber: Function;
addNumber: Function;
fetchHomeMultidata: Function;
banners: [];
recommends: [];
}
export function About(props: Props) {
const { counter, banners, recommends } = props;
useEffect(() => {
props.fetchHomeMultidata('about');
}, [counter]);
return (
<div>
<h1>About</h1>
<div>
<h3>About中的按钮---要求的数字{counter}</h3>
<button onClick={() => props.addNumber(6)}>+6</button>
<button onClick={() => props.subNumber(6)}>-6</button>
</div>
{/* 渲染 */}
<ul>
{banners.map((item: any) => (
<li key={item.boardId}>{item.cover}</li>
))}
</ul>
{/* 渲染 */}
<ul>
{recommends.map((item: any) => (
<li key={item.boardId}>About中boardId={item.boardId}</li>
))}
</ul>
</div>
);
}
/** 用于赋值 */
const mapStateToProps = (state: any) => ({
counter: state.counter.counter,
banners: state.home.banners,
recommends: state.home.recommends,
});
const mapDispatchToProps = (dispatch: any) => ({
addNumber(num: number) {
dispatch(addNumber(num));
},
subNumber(num: number) {
dispatch(subNumber(num));
},
fetchHomeMultidata(str: string) {
dispatch(fetchHomeMultidataAction(str));
},
});
// 用于派发请求
export default connect(mapStateToProps, mapDispatchToProps)(About);