React-RTK

​🌈个人主页:前端青山

🔥系列专栏:React篇

🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来React篇专栏内容:React-RTK

目录

1、介绍

2、安装

3、编写RTK使用示例

4、官方提供项目包示例

[创建 Redux Store](#创建 Redux Store)

[定义 Slice](#定义 Slice)

[创建 Async Thunk](#创建 Async Thunk)

[在 React 组件中使用](#在 React 组件中使用)

1、介绍

Redux是reactjs中进行组件状态共享的js库,工具。基于flux思想实现

ReduxToolKit 是redux官方提供的一种编写redux的范本。toolkit工具包

2、安装

复制代码
# yarn
​
javascript 复制代码
yarn add redux @reduxjs/toolkit react-redux

3、编写RTK使用示例

store/index.js

javascript 复制代码
/**
 * 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

javascript 复制代码
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的计算器实例

javascript 复制代码
# 生成RTK项目包
npx create-react-app rtk-ts --template redux-typescript
​
# yarn
yarn create react-app rtk-ts --template redux-typescript

React-RTK 的作用

  1. 简化 Redux 开发流程 :React-RTK 提供了一系列预封装的工具函数和中间件,如 createSlicecreateAsyncThunk 等,大大减少了编写 Redux 相关代码的工作量,避免了繁琐的样板代码。

  2. 提升代码质量与可维护性:RTK 遵循 Redux 最佳实践,确保代码结构清晰、逻辑一致。内置的 Immer 库允许通过修改现有状态的副本来描述状态更新,无需手动实现 immutability。同时,TypeScript 支持增强了类型安全。

  3. 优化性能与开发体验 :RTK 自动配置 Redux DevTools Extension,方便开发者监控和调试应用状态变化。它还默认集成了 redux-thunk 以支持异步操作,并通过代码生成优化了 store 的创建过程。

创建 Redux Store

首先,使用 configureStore 函数创建 Redux store,通常在应用的主入口文件(如 index.jsApp.js)中进行:

javascript 复制代码
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:

javascript 复制代码
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:

javascript 复制代码
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 组件中,通过 useSelectoruseDispatch 钩子访问和操作 store:

javascript 复制代码
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;
相关推荐
小白小白从不日白7 分钟前
react 组件通讯
前端·react.js
c4fx17 分钟前
Delphi5利用DLL实现窗体的重用
开发语言·delphi·dll
罗_三金17 分钟前
前端框架对比和选择?
javascript·前端框架·vue·react·angular
鸽芷咕40 分钟前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
Jhxbdks1 小时前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java6666688881 小时前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存1 小时前
源码分析:LinkedList
java·开发语言
代码雕刻家1 小时前
数据结构-3.1.栈的基本概念
c语言·开发语言·数据结构
Fan_web1 小时前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
梦想科研社1 小时前
【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
开发语言·算法·数学建模·matlab·无人机