🌈个人主页:前端青山
🔥系列专栏:React篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来React篇专栏内容:React-RTK
目录
1、介绍
2、安装
3、编写RTK使用示例
4、官方提供项目包示例
创建 Redux Store
定义 Slice
创建 Async Thunk
在 React 组件中使用
1、介绍
Redux是reactjs中进行组件状态共享的js库,工具。基于flux思想实现
ReduxToolKit 是redux官方提供的一种编写redux的范本。toolkit工具包
2、安装
# yarn
yarn add redux @reduxjs/toolkit react-redux
3、编写RTK使用示例
store/index.js
/**
* createSlice 创建分片 分模块
* configureStore 配置store仓库
* RTK工具库里带的方法
*
* */
import { createSlice, configureStore } from '@reduxjs/toolkit'
const counterSlice = createSlice({
// 模块的命名
name: 'counter',
// state初始值
initialState: {
value: 0
},
// 操作方法
reducers: {
// action 代表处理的对象参数
// type:执行的方法名称
// payload:传递的参数
incremented: (state,action) => {
console.log(action);
// Redux Toolkit 允许在 reducers 中编写 "mutating" 逻辑。
// 它实际上并没有改变 state,因为使用的是 Immer 库,检测到“草稿 state”的变化并产生一个全新的
// 基于这些更改的不可变的 state。
state.value += action.payload
console.log(state.value);
},
decremented: (state) => {
state.value -= 1
}
}
})
export const { incremented, decremented } = counterSlice.actions
// 将各模块汇总 进行配置为同一的store
const store = configureStore({
reducer: counterSlice.reducer
})
export default store
// 可以订阅 store
// store.subscribe(() => console.log(store.getState()))
// 将我们所创建的 action 对象传递给 `dispatch`
// store.dispatch(incremented())
// {value: 1}
// store.dispatch(incremented())
// {value: 2}
// store.dispatch(decremented())
// {value: 1}
App.jsx
import React, { Component } from 'react'
// 导入store
import store, { incremented } from './store'
export default class App extends Component {
// 初始化操作
constructor() {
super()
// 监听器 订阅 订阅state变化
store.subscribe(() => {
this.setState({ value: store.getState().value })
})
}
state = {
value: 0
}
render() {
// console.log(store.getState().value)
return (
<div>
<button onClick={() => store.dispatch(incremented(100))}>
{this.state.value}
</button>
</div>
)
}
}
4、官方提供项目包示例
redux官方提供了一个RTK工具包编写的redux的计算器实例
# 生成RTK项目包
npx create-react-app rtk-ts --template redux-typescript
# yarn
yarn create react-app rtk-ts --template redux-typescript
React-RTK 的作用:
-
简化 Redux 开发流程:React-RTK 提供了一系列预封装的工具函数和中间件,如
createSlice
、createAsyncThunk
等,大大减少了编写 Redux 相关代码的工作量,避免了繁琐的样板代码。 -
提升代码质量与可维护性:RTK 遵循 Redux 最佳实践,确保代码结构清晰、逻辑一致。内置的 Immer 库允许通过修改现有状态的副本来描述状态更新,无需手动实现 immutability。同时,TypeScript 支持增强了类型安全。
-
优化性能与开发体验:RTK 自动配置 Redux DevTools Extension,方便开发者监控和调试应用状态变化。它还默认集成了
redux-thunk
以支持异步操作,并通过代码生成优化了 store 的创建过程。
创建 Redux Store
首先,使用 configureStore
函数创建 Redux store,通常在应用的主入口文件(如 index.js
或 App.js
)中进行:
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers'; // 导入已合并的 Reducer
const store = configureStore({
reducer: rootReducer,
});
// 如果使用 React-Router,可能需要将 store 与 Provider 组件一起包裹应用
import { Provider } from 'react-redux';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
定义 Slice
使用 createSlice
函数来定义一个 Redux slice,包含相关的 action types、action creators 和 reducer:
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
items: [],
loading: false,
error: null,
};
const mySlice = createSlice({
name: 'mySlice',
initialState,
reducers: {
// 纯同步 reducer
addItem(state, action) {
state.items.push(action.payload);
},
removeItem(state, action) {
state.items = state.items.filter(item => item.id !== action.payload);
},
},
extraReducers: builder => {
// 异步操作处理(通常使用 createAsyncThunk 创建)
builder.addCase(fetchItems.pending, state => {
state.loading = true;
state.error = null;
});
builder.addCase(fetchItems.fulfilled, (state, action) => {
state.items = action.payload;
state.loading = false;
});
builder.addCase(fetchItems.rejected, (state, action) => {
state.loading = false;
state.error = action.error.message;
});
},
});
export const { addItem, removeItem } = mySlice.actions;
export default mySlice.reducer;
创建 Async Thunk
对于涉及异步操作(如 API 调用)的状态变更,使用 createAsyncThunk
创建一个 thunk action:
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
export const fetchItems = createAsyncThunk('mySlice/fetchItems', async () => {
const response = await axios.get('/api/items');
return response.data;
});
在 React 组件中使用
在 React 组件中,通过 useSelector
和 useDispatch
钩子访问和操作 store:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addItem, removeItem, fetchItems } from './mySlice';
function ItemList() {
const dispatch = useDispatch();
const { items, loading, error } = useSelector(state => state.mySlice);
useEffect(() => {
dispatch(fetchItems());
}, [dispatch]);
const handleAddItem = () => {
const newItem = /* 新建一个 item 对象 */;
dispatch(addItem(newItem));
};
const handleRemoveItem = (itemId) => {
dispatch(removeItem(itemId));
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
{/* 渲染 items 列表,添加/删除按钮 */}
</div>
);
}
export default ItemList;