reactjs18 中使用@reduxjs/toolkit同步异步数据的使用

react18 中使用@reduxjs/toolkit

1.安装依赖包

bash 复制代码
yarn add @reduxjs/toolkit react-redux

2.创建 store

根目录下面创建 store 文件夹,然后创建 index.js 文件。

js 复制代码
import { configureStore } from "@reduxjs/toolkit";
import { counterReducer } from "./features/counter";
import counterReducers from "./modules/counterStore";
import channelReducers from "./modules/channelStore";

export const store = configureStore({
  reducer: {
    counterReducers,
    channelReducers,
  },
  middleware: (getDefaultMiddleware) => {
    const middlewares = getDefaultMiddleware();
    return [...middlewares /* ... */];
  },
});

export default store;

3.创建模块

在 store 文件夹下面创建 modules 文件夹,然后创建 counterStore.js 和 channelStore.js 文件。

js 复制代码
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
  name: "counter",
  initialState: {
    count: 10,
  },
  reducers: {
    increase(state) {
      state.count += 1;
    },
    decrease(state) {
      state.count -= 1;
    },
    addToNum(state, action) {
      state.count += action.payload;
    },
  },
});

const { increase, decrease, addToNum } = counterStore.actions;
const reducer = counterStore.reducer;
//导出给组件使用
export { increase, decrease, addToNum };
//导出reducer,给store使用
export default reducer;
js 复制代码
import { createSlice } from "@reduxjs/toolkit";

const store = createSlice({
  name: "channel",
  initialState: {
    channelLists: [
      {
        id: 1,
        name: "React",
      },
    ],
  },
  reducers: {
    setChannels(state, action) {
      //下拉分页时,追加数据
      // state.channelLists = [...state.channelLists, ...action.payload];
      //上拉刷新时,替换数据
      state.channelLists = action.payload;
    },
  },
});

const { setChannels } = store.actions;
const reducer1 = store.reducer;

//异步请求
const fetchChannel = () => {
  //返回一个新函数
  return async (dispatch) => {
    //封装异步请求
    const response = await fetch("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    const data = await response.json();
    //派发action,触发同步的reducer
    dispatch(setChannels(data));
  };
};
//导出给组件使用
export { setChannels, fetchChannel };
//导出reducer,给store使用
export default reducer1;

@reduxjs/toolkit 思路有点类似与 vuex,但是 vuex 是 vue 的插件,而@reduxjs/toolkit 是 react 的库。

在异步操作时,都是用在异步方法中,去调用同步的方法来更新数据,vue中commit,@reduxjs/toolkit中使用dispatch

4.使用 store

在全局组件中引入 store,然后使用 Provider 包裹。

js 复制代码
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./store";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>

5.使用组件

在组件中引入 store,然后使用 useSelector 获取数据。

js 复制代码
import "./App.css";
import { useState, useEffect } from "react";
import "./style.css";
import store from "./store";
import { useSelector, useDispatch } from "react-redux";
import { increase, decrease, addToNum } from "./store/modules/counterStore";
import { fetchChannel } from "./store/modules/channelStore";

function App() {
  const { count } = useSelector((state) => state.counterReducers);
  const { channelLists } = useSelector((state) => state.channelReducers);
  console.log("🚀 ~ App ~ channelLists:", channelLists);
  const dispatch = useDispatch();

  const handleAdd = () => {
    dispatch(increase(5));
  };
  const handleMinus = () => {
    dispatch(decrease());
  };

  const handleAddTen = () => {
    dispatch(addToNum(10));
  };
  //组件加载时,自动触发一次请求
  // useEffect(() => {
  //   dispatch(fetchChannel());
  // }, [dispatch]);

  //点击按钮时加载数据
  const handleGetUserLists = () => {
    // dispatch({ type: "GET_USER_LISTS" });
    dispatch(fetchChannel());
  };

  const renderUserLists = () => {
    return channelLists?.map((item, index) => {
      return (
        <li key={index}>
          <img width="50px" src={item.avatar_url} />
          <span>{item.login}</span>
        </li>
      );
    });
  };

  return (
    <div className="App">
      <button onClick={handleAdd}>add</button>
      <button onClick={handleAddTen}>add 10</button> {count}
      <button onClick={handleMinus}>minus</button>
      <button onClick={handleGetUserLists}>获取用户列表</button>
      <ul>{renderUserLists()}</ul>
    </div>
  );
}

export default App;
相关推荐
前端李易安19 分钟前
ajax的原理,使用场景以及如何实现
前端·ajax·okhttp
汪子熙1 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
Envyᥫᩣ1 小时前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.5 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。6 小时前
案例-表白墙简单实现
前端·javascript·css
数云界6 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd6 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常6 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer6 小时前
Vite:为什么选 Vite
前端
小御姐@stella6 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js