轻松搞定 reduxjs/toolkit

简介: 轻松搞定 reduxjs/toolkit

1. 前言

  1. toolkit
  2. 最近创建 react脚手架项目的时候发现, 默认安装的 react版本已经变为18X了,
  3. 原来的项目换成18X也能运行,但是 redux中的createStore出现了横岗也就是被废弃了
  4. 那就看看 新出的啥东西代替了createStore,体验下好用不

2. 是什么 what

Redux Toolkit包旨在成为编写Redux逻辑的标准方式。它最初的创建是为了帮助解决关于 Redux 的三个常见问题:

  1. 配置 Redux 存储太复杂了
  2. 我必须添加很多包才能让 Redux 做任何有用的事情
  3. Redux 需要太多样板代码

3. 环境安装

注意不要拼错 @reduxjs/toolkit

npm install @reduxjs/toolkit  react-redux

yarn add @reduxjs/toolkit  react-redux

react-redux 也需要单独安装


4. configureStore

  1. configureStore替代 createStore
  2. 配置简单,设置默认值也方便
  3. src/store/index.js

// 引入
import {configureStore} from '@reduxjs/toolkit'
import counterSlice from "../pages/basic/counterSlice"
import mySlice from "../pages/mySlice"
export default configureStore({
  reducer:{
    rootCounter:counterSlice,
    rootMy:mySlice
  }
})
  1. 这里 reduer直接合并成一个唯一的 根root了
  2. 原有的combineReducers这个合并函数就用不到了
  3. 注意自己配置的 reducer的 key值 和 对应的value值
  4. 我这里把单独的 reducer 放到和页面同级了,这个根据自己的习惯,放到 store下面新建目录存放所有的reducer也行

5. 根组件配置 store

  1. 入口index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import store from './store'
import {Provider} from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
   <Provider store={store}>
         <App />
    </Provider>
  </React.StrictMode>
);

6.  createSlice reducer编写

1. 创建slice

使用createSlice方法创建一个slice。每一个slice里面包含了reducer和actions,可以实现模块化的封装。

所有的相关操作都独立在一个文件中完成。

2. 关键属性:

  1. name
    命名空间,可以自动的把每一个action进行独立,解决了action的type出现同名的文件。在使用的时候默认会把使用name/actionName
  2. initialState
    state数据的初始值

3.reducers

定义的action。由于内置了immutable插件,可以直接使用赋值的方式进行数据的改变,不需要每一次都返回一个新的state数据。

import { createSlice } from "@reduxjs/toolkit";
const initialState = {
  counter: 100,
  user: {
    name: "yzs",
    job: "全栈",
  },
};
export const counterSlice = createSlice({
  name: "counterSpace", // 命名空间,在调用action的时候会默认的设置为action的前缀,保证唯一.不重名
  initialState,
  reducers: {
// reducer函数 state当前组件的数据 
//第二个参数为{payload:{},type:"""} 想想就写法或者vuex
    increment(state) {
      state.counter += 100;
    },
    decrement(state, actions) {
      // actions == {payload:{},type:"""}
      console.log("decrement---actions", actions);
      state.counter -= actions.payload;
    },
    updateUser(state, { payload }) {
      console.log("updateUser-------payload", payload);
// 引用类型 注意 赋值的写法
      state.user = {
        ...state.user,
        ...payload,
      };
    },
  },
});
export const { increment, decrement, updateUser } = counterSlice.actions;
export const selectCount = (state) => state.rootCounter.counter;
export const selectUser = (state) => state.rootCounter.user;
export default counterSlice.reducer;

3. 导出

  1. counterSlice.actions 导出所有的修改函数方便页面使用
  2. counterSlice.reducer 导出reducer在 store里面使用

4. 具体reducer 函数的参数

参数1: 当前slice的state数据

参数2: 对象{type:"",payload:传参}

type:counterSpace/decrement

type就是之前的 actions用switc/case来匹配很麻烦,现在简洁了

type构成 slice的 name命名空间/具体的修改函数

payload 要和传的时候保持一致


7. 页面使用

7.1. useSelector()

  1. 返回指定的 state

// 这样写太长了 麻烦
 const counter = useSelector(state=>state.rootCouter.counter);
  1. rootCouter这个key 来源于 根 store里面配置的reducer
  2. 这样写太长了 麻烦
  3. 在这个 slice里面我做了统一处理

export const selectCount = (state) => state.rootCounter.counter;
export const selectUser = (state) => state.rootCounter.user;
  1. 页面使用

import { useSelector, useDispatch } from "react-redux";
import {
  increment,
  decrement,
  updateUser,
  selectCount,
  selectUser,
} from "./normalSlice";
export default function Counter() {
  const dispatch = useDispatch();
  // let counter = useSelector(state=>state.rootCouter.counter)
  const counter = useSelector(selectCount);
  console.log("页面---counter:", counter);
  const user = useSelector(selectUser);
// 这样可以直接解构出当前 slice所有的 state
// 具体用哪种 看自己心情
 const { counter } = useSelector((state) => state.rootCouter);
return ( <div> 布局看下面 </div>)

7.2 useDispatch()

const dispatch = useDispatch(); 修改函数

return (
    <div>
      <h1>reduxjs/toolkit 基础用法</h1>
      <hr />
      <button onClick={() => dispatch(increment())}>+</button>
      <span>{counter}</span>
      <button onClick={() => dispatch(decrement(666))}>-</button>
      <hr />
      <h1>姓名:{user.name} ---职业:{user.job}</h1>
      <button onClick={()=>{dispatch(updateUser({name:'Michael'}))}}>改名</button>
      <button onClick={()=>{
        dispatch(updateUser({job:'自由职业者'}))}
        }>转行</button>
    </div>
  );
}
  1. payload传参和 reducer保持一致
  2. 引用类型的 修改注意

8.  异步 createAsyncThunk()

  1. 接受一个动作类型字符串和一个返回Promise函数,并生成一个pending/fulfilled/rejected基于该Promise分派动作类型的 thunk
  2. 用 fetch请求模拟一个异步
    3.createAsyncThunk("counterSpace/getList",()=>{})
  3. 参数1: slice的name/命名空间/函数名

// return 不要忘记
export const getList = ( ) => {
return fetch("https://.XX.cn/api/news").then(res=>res.json());
};
export const  getListAsync =  createAsyncThunk("counterSpace/getList",async()=>{
  const res = await getList()
  return res// 此处的返回结果会在 .fulfilled中作为payload的值
});

9.extraReducers

  1. 异步函数配置

createSlice({
    name: "counterSpace",
    initialState,
    reducers:{},
    extraReducers: (builder) => {
    builder
      .addCase(getListAsync.pending, (state) => {
         console.log("pending",state);
      })
      .addCase(getListAsync.rejected, (state, err) => {
        console.log("rejected 失败",err);
      })
      .addCase(getListAsync.fulfilled, (state, action) => {
         console.log("fulfilled 成功",state);
        console.log("fulfilled action",action);
        state.list = action.payload
      });
  },
});
  1. 这个配置基本就是套路
  2. 只需要把函数名字改为通过createAsyncThunk()创建的函数名
  3. 根据自己的业务场景 写赋值逻辑就行

10. 页面使用异步函数

<button onClick={()=>dispatch(getListAsync('异步模拟'))}>异步</button>
      <ul>
        {
          listData.map((news)=>{
            return <li key={news.id}>{news.title}</li>
          })
        }
      </ul>
  1. 效果图 image.png
    1.png
  2. 也可以传参数

参考资料

redux-toolkit


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理,如有错误,道友们一起沟通交流;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉


相关文章
|
Python Windows
JetBrains 插件市场安装 Cloud Toolkit
通过 JetBrains 插件市场安装 Alibaba Cloud Toolkit
53706 0
JetBrains 插件市场安装 Cloud Toolkit
|
6月前
|
文字识别 Linux 计算机视觉
toolkit-frame之toolkit-tools(实用功能)
toolkit-frame之toolkit-tools(实用功能)
49 0
|
监控 安全 测试技术
Cloud Toolkit
Cloud Toolkit 是一款基于 Eclipse 的云计算开发工具,由阿里云提供,可以帮助开发人员更方便地在阿里云上进行云计算应用的开发和调试。
144 2
|
弹性计算 运维 监控
Cloud Toolkit
Cloud Toolkit是阿里云提供的一款IDE插件,用于在Eclipse和IntelliJ IDEA中开发和部署阿里云应用程序。通过Cloud Toolkit,您可以方便地创建、调试、部署和管理阿里云应用程序,提高开发和运维效率。
142 1
|
JavaScript
推荐一款工具 -- Watt Toolkit
你是否在为访问Github速度慢而发愁?来来来,推荐你一款工具试试 「Watt Toolkit」是一个开源跨平台的多功能游戏工具箱。 网络加速 使用 YARP.ReverseProxy 开源项目进行本地反代来支持更快的访问游戏网站。 脚本配置 通过加速服务拦截网络请求将一些 JS 脚本注入在网页中,提供类似网页插件的功能。 账号切换 一键切换已在当前 PC 上登录过的 Steam 账号,与管理家庭共享库排序及禁用等功能。
4741 0
推荐一款工具 -- Watt Toolkit
|
Arthas 监控 IDE
Cloud Toolkit云插件的使用
Cloud Toolkit是阿里云官方出品的一款插件,可以有效提高工程师开发、测试、部署、监控效率,它的远程监控诊断是通过Arthas实现的。
378 0
|
弹性计算 IDE 开发工具
3分钟,了解阿里云热门开发者工具 Cloud Toolkit
阿里云 Toolkit (Alibaba Cloud Toolkit) 是一个面向 IDE(如 Eclipse 或 IntelliJ IDEA )的插件,帮助开发者更高效的开发、测试、诊断并部署适合云端运行的应用。
92397 21
|
Java Maven Android开发
《Cloud Toolkit User Guide》
Alibaba Cloud Toolkit,面向 IDE(如 Eclipse 或 IntelliJ IDEA )的插件,帮助开发者更高效的开发、测试、诊断并部署适合云端运行的应用
38306 1
|
Android开发 Python Java
安装 Alibaba Cloud Toolkit
安装指南
27000 0