React 基础巩固(三十五)——ReduxToolKit (RTK)
一、RTK介绍
-
Redux Tool Kit (RTK)是官方推荐的编写Redux逻辑的方法,旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题。
-
RTK的核心API主要有如下几个:
-
configureStore:包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的slice reducer,添加你提供的任何Redux中间件,redux-thunk默认包含,并启用Redux DevTools Extension。
参数 描述 reducer 将slice中的reducer组成一个对象传入此处 middleware 传入中间件 devTools 是否配置devTools工具,默认为true -
createSlice:接受reducer函数的对象、切片名和初始状态值,并自动生成切片reducer,并带有相应的actions。
参数 描述 name 用户标记slice的名次 initialState 初始化值 reducers reducer函数,对象类型,可添加多个 createSlice 返回值是一个对象,包含所有的actions -
createAsyncThunk:接受一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的thunk。
-
二、RTK的简单使用
-
安装 toolkit 和 react-redux
npm install @reduxjs/toolkit react-redux
-
利用 createSlice 构建store分片(store/features/counter.js)
import { createSlice } from "@reduxjs/toolkit"; // createSlice(用户标记slice的名称, ) const counterSlice = createSlice({ name: "counter", initialState: { counter: 989, }, reducers: { addNumber(state, {payload}) { console.log("add number", payload); state.counter = state.counter + payload; }, subNumber(state, {payload}) { console.log("sub number", payload); state.counter = state.counter - payload; }, }, }); export const { addNumber, subNumber } = counterSlice.actions; export default counterSlice.reducer;
-
利用configureStore 配置store(store/index.js)
import { configureStore } from "@reduxjs/toolkit"; import counterReducer from "./features/counter"; const store = configureStore({ reducer: { counter: counterReducer, }, }); export default store;
-
利用react-redux,依照往常的做法,将store注入index.js
import React from "react"; import ReactDOM from "react-dom/client"; import { Provider } from "react-redux"; import App from "./App"; import store from "./store"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( // <React.StrictMode> <Provider store={store}> <App /> </Provider> // </React.StrictMode> );
-
利用react-redux,依照往常的做法,在需要使用store及dispatch操作的页面文件中通过connect进行连接
// Home.jsx import React, { PureComponent } from "react"; import { connect } from "react-redux"; import { addNumber } from "../store/features/counter"; export class Home extends PureComponent { addNumber(num) { this.props.addNumber(num); } render() { const { counter } = this.props; return ( <div> home:{counter} <button onClick={(e) => this.addNumber(5)}>+5</button> <button onClick={(e) => this.addNumber(8)}>+8</button> <button onClick={(e) => this.addNumber(18)}>+18</button> </div> ); } } const mapStateToProps = (state) => ({ counter: state.counter.counter, }); const mapDispatchToProps = (dispatch) => ({ addNumber(num) { dispatch(addNumber(num)); }, }); export default connect(mapStateToProps, mapDispatchToProps)(Home);
// Profile.jsx import React, { PureComponent } from "react"; import { connect } from "react-redux"; import { subNumber } from "../store/features/counter"; export class Profile extends PureComponent { subNumber(num) { this.props.subNumber(num); } render() { const { counter } = this.props; return ( <div> profile:{counter} <button onClick={(e) => this.subNumber(5)}>-5</button> <button onClick={(e) => this.subNumber(8)}>-8</button> </div> ); } } const mapStateToProps = (state) => ({ counter: state.counter.counter, }); const mapDispatchToProps = (dispatch) => ({ subNumber(num) { dispatch(subNumber(num)); }, }); export default connect(mapStateToProps, mapDispatchToProps)(Profile);
-
将界面引入App.jsx
import React, { PureComponent } from "react"; import { connect } from "react-redux"; import Home from "./pages/Home"; import Profile from "./pages/Profile"; import "./style.css"; export class App extends PureComponent { render() { const { counter } = this.props; return ( <div> <h2>App Counter: {counter}</h2> <div className="pages"> <Home /> <Profile /> </div> </div> ); } } const mapStateToProps = (state) => ({ counter: state.counter.counter }); export default connect(mapStateToProps)(App);
-
查看运行结果,和之前单独使用react-redux的效果一致,但在代码层面上化繁为简