Redux Toolkit 是什么?

Redux Toolkit 是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式,我们强烈建议你使用它。

它包括几个实用程序功能,这些功能可以简化最常见场景下的 Redux 开发,包括配置 store、定义 reducer,不可变的更新逻辑、甚至可以立即创建整个状态的 “切片 slice”,而无需手动编写任何 action creator 或者 action type。它还自带了一些最常用的 Redux 插件,例如用于异步逻辑 Redux Thunk,用于编写选择器 selector 的函数 Reselect ,你都可以立刻使用。

  1. 本质:redex和redux-thunk进行封装

  2. 核心:

  • 仓库,存放全局数据

  • reducer:定义修改该数据的行为(方法)的

  • actions:行为

一、安装

# NPM
npm install @reduxjs/toolkit # Yarn
yarn add @reduxjs/toolkit

二、创建文件夹store/index:创建仓库

Redux Toolkit API文档:

  1. configureStore

    1. 作用:创建仓库,返回值就是一个仓库

    2. 语法:let store = configureStore({各自的reducer}) ; // 合并reducer

    代码实现:在store文件夹创建一个index.js文件,在里面引入各自的reduce,集中关联 reducer

import {configureStore,createSlice} from '@reduxjs/toolkit'

import meReducer from './modules/MeState'
import cartReducer from './modules/CartState'
import LimitReducer from './modules/LimitState'
//configureStore =》语法
//返回值 =》就是仓库
//configureStore({各自的reducer}) =>合并reducer //创建仓库
const store = configureStore({
reducer: { //模块化对象
me:meReducer,
cart:cartReducer,
limit:LimitReducer
}
}) console.log(store);
// export default store //创建仓库 =》让仓库和react 进行关联 react-redux
export default store
  1. createSlice

    1. 作用:存放仓库中的数据,和定义仓库的行为(创建各自的reducer)

    2. 语法:let Mystate= createSlice({ }); // 创建reducer,存放数据initalState,定义行为reducers

在store/modules中创建MeState,定义reducer

import {createSlice} from '@reduxjs/toolkit'

// 创建 reducer => 存放仓库数据,和定义仓库的行为
// 作用:createSlice => 创建 各自的reducer
// 语法
// 返回值 = createSlice => 对象
// createSlice({实例属性})
let MeState=createSlice({
name:'me', // 作用域 唯一标识 => 我的模块存放的全局数据
initialState:{
name:'我是小明',
age:20,
num:100,
},
// reducer =》 定义方法修改仓库中的数据
// 相对 vue muations => 定义修改 仓库中的数据
reducers:{
changeName(state,val){ // 第一个参数 就是这个仓库的存放(模板)的数据 第二个参数 就是 调用这个方法传递过来的数据
console.log(val);
// 重新创建仓库数据吗?return {num:最新的数据} =>
state.name=val.payload; // 就是对数据进行更新
},
addAge(state){
state.age+=1;
},
addNum(state,val){
state.num=state.num+val.payload;
}
}
}) console.log(MeState); // 将行为暴露出去
export let {changeName,addAge,addNum}=MeState.actions // 本质就是将这个方法暴漏出去 export default MeState.reducer

三、使用React-redux,让仓库数据与react产生关联

核心:为我们react项目提供的一个组件,两个hooks

组件:Provider 1 作用:在父级组件中提供数据 ,其他的子集组件就可以获取到;

2 在父组件中提供了数据 store;

hooks:

    useSelector: 1 作用:在组件中获取仓库中的数据,再通过useState修改数据方法,让数据更新

2 语法:useSelector(state => { return 返回值}) // 返回 在仓库中获取的数据

useDispatch 1 作用:可以获取到更新组件的dispatch,先触发reducer,

2 语法:let dispatch=useDispatch(); ​ dispatch({type:'add'});

1. 安装react-redux

npm i react-redux

2. 在index.js中使用react-redux

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

四、在组件中使用仓库中的数据

import './App.css';
// (1)引入 react-redux 中提供的两个方法
import { useSelector,useDispatch } from 'react-redux';
// (2) 在页面(组件中获取数据)
import {add,sub,addLIst,subList} from './store/modules/CartState' import { changeName,addNum} from './store/modules/MeState'; function App() {
let dispatch=useDispatch();
// (3) 注意我们的行为 => 需要我们暴露处理 => 而这些行为就是reducers中定义的方法
let state =useSelector(store=>store);
console.log(state)
return (
<div className="App">
<h2> 获取到仓库中的数据{state.me.name}</h2>
<h3>CartState {state.cart.num}</h3>
<h3>MeState {state.me.num}</h3> {/*
修改仓库中数据
三点核心属性:
reducer
actions => dispatch(行为)
store
*/}
<button onClick={()=>{dispatch(changeName("我不是小明"))}}>修改MeName中的数据</button> <button onClick={()=>{dispatch(add(10))}}>修改CartState仓库中的数据num</button> <button onClick={()=>{dispatch(addNum(10))}}>修改MeState仓库中的数据num</button>
</div>
);
} export default App;

五、处理仓库中的复杂数据类型

处理方法:就是使用操作复杂数据类型的方法

  1. 使用configureStore创建仓库,使用createSlice定义reducer

import {configureStore,createSlice} from '@reduxjs/toolkit'

//创建reducer =>createSlice
let reducerNum = createSlice({
name:'nums',// 空间命名
initialState:{
num:2,
list:[1,2,3,4,5]
},
// 相对于vue mutations =》 定义方法修改 仓库中的数据
reducers:{
//在这里定义的方法 (1)第一个参数 当前reducer 的数据 (2) actions
add(state,data){
console.log(state,data.payload);
// 重新创建仓库数据吗? return {num:最新的数据} =》
state.num = state.num+data.payload // 就是对数据进行更新
},
reduce(state){
state.num = state.num -1
},
// 写的方法寓意化一下
addList(state,data){
state.list.push(data.payload)
},
reduceList(state,data){
state.list.splice(data.payload,1)
}
}
}) //注意 暴露actions
export let {add,reduce,addList,reduceList} = reducerNum.actions // console.log( reducerNum); // 创建 store
//configureStore => 创建仓库
// 语法: configureStore({ reducer:{}})
export default configureStore({
reducer:{
//写reducer
reducerNum:reducerNum.reducer
}
})

在组件中使用仓库:使用userSelector引入仓库总的reducer和方法actions

  1. 语法:let {actions} = userSelector(store=> store.reducerNum)

import {add,reduce,addList,reduceList} from './store/index'
function App() {
let {num,list} = useSelector(store=>store.reducerNum) //{num,list}
let dispatch = useDispatch()
// console.log(store);
return (
<div className="App">
<h2>toolkit</h2>
<h2>{num}</h2>
<button onClick={()=>dispatch(add(2))}>+</button>
<button onClick={()=>dispatch(reduce())}>-</button>
{
list.map((item,index)=>{
return<div key={index} onClick={()=>dispatch(reduceList(index))}>{item}</div>
})
}
<button onClick={()=>dispatch(addList(1000))}>添加list</button>
</div>
);
}

六、处理异步问题

之前在redux中需要引入 第三方插件:react-thunk,而使用了redux Tookit是内置了react-thunk,

  1. 定义异步acitons

// 自己定义异步actions

// 1 获取到异步的数据,再触发reducer => 修改仓库中的数据
// 2 定义 actions export function getRouterData(){ // 异步actions
// 1 获取到异步的数据
function getData(){
// get需要传参,否则会报错
return axios.get('').then(res=>{
// 获取到的是异步的数据
let routerList=[1,2,3,4,5];
return routerList
})
} // 2 再触发 reducer
return async (dispatch)=>{ // 返回的处理方法的第一个参数就是 dispatch
let data =await getData(); // 获取到异步的数据 dispatch(addRouter(data))
}
}

2.需要在reducer  定义方法,然后在组件中操作这个方法

import {createSlice} from '@reduxjs/toolkit';
import axios from 'axios'; let LimitState=createSlice({
name:'limit',
initialState:{
router:[]
},
reducers:{ // 只能处理同步问题的问题
addRouter(state,data){
console.log('获取到异步的路由信息',data);
// router 的数据是后端给的 payload
state.router=data.payload
}
}
}) // 注意 => 暴露两个
// 1 reducers 中的行为 => 那个组件使用直接引入
export let {addRouter}=LimitState.actions; export default LimitState.reducer;

3. 在组件中触发异步actions,

  1. dispatch(异步actions方法的调用),调用的这个是异步actions的方法,然后再通过reduceer修改异步数据

import './App.css';
// (1)引入 react-redux 中提供的两个方法
import { useSelector,useDispatch } from 'react-redux';
// (2) 在页面(组件中获取数据)
import { getRouterData } from './store/modules/LimitState'; function App() {
let dispatch=useDispatch(); let state =useSelector(store=>store);
console.log(state)
return (
<div className="App">
<h2> 获取到仓库中的数据{state.limit.router}</h2>
<button onClick={()=>dispatch(getRouterData())}>仓库中获取到异步的数据</button>
</div>
);
} export default App;

Redux Toolkit 的使用方法的更多相关文章

  1. Redux 的困扰与如何技术选型

    文章的名字我想了很久,备选项有"我再不推荐 Redux","Redux 为什么令我头疼","Redux 进化启示录"等等.通过这一系列名字我 ...

  2. 【原创】Redux 卍解

    Redux 卍解 Redux - Flux设计模式的又一种实现形式. 说起Flux,笔者之前,曾写过一篇<ReFlux细说>的文章,重点对比讲述了Flux的另外两种实现形式:『Facebo ...

  3. Redux教程2:链接React

    通过前面的教程,我们有了简单的环境,并且可以运行Redux的程序,也对 如何编写Redux示例 有了初步的印象: 掌握了 使用Redux控制状态转移 ,继而驱动 React 组件发生改变,这才是学习R ...

  4. 【原】redux学习笔记

    上周学习了flux,这周研究了一下redux,其实很早之前都已经在研究他们了,只是之前一直没搞懂,最近这两周可能打通了任督二脉,都算入门了. 写博客的目的主要是做一下笔记,总结一下思路,以及和大家交流 ...

  5. (原)Ubuntu16中安装cuda toolkit

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5655957.html 参考网址: https://devtalk.nvidia.com/default ...

  6. 详解 Node + Redux + MongoDB 实现 Todolist

    前言 为什么要使用 Redux? 组件化的开发思想解放了繁琐低效的 DOM 操作,以 React 来说,一切皆为状态,通过状态可以控制视图的变化,然后随着应用项目的规模的不断扩大和应用功能的不断丰富, ...

  7. koa/redux middleware系统解析

    middleware 对于现有的一些框架比如koa,express,redux,都需要对数据流进行一些处理,比如koa,express的请求数据处理,包括json.stringify,logger,或 ...

  8. React从入门到放弃之前奏(4):Redux中间件

    redux 提供了类似后端 Express 的中间件概念. 最适合扩展的是redux中的 store.dispatch 方法,中间件实际就是通过 override redux的store.dispat ...

  9. 教你如何在React及Redux项目中进行服务端渲染

    服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...

  10. 一起学习造轮子(二):从零开始写一个Redux

    本文是一起学习造轮子系列的第二篇,本篇我们将从零开始写一个小巧完整的Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Red ...

随机推荐

  1. RabbitMq了解

    RibbitMQ MQ优势 MQ的三大主要作用: 应用解耦.异步提速.流量削锋 应用解耦 系统的耦合性越高,容错性就越低,可维护性就越低: 解耦: 如果其中一个系统服务宕机,那么系统的其他服务将也无法 ...

  2. laravel框架 forelse和foreach

    1. @forelse($data as $v) 循环数据内容..... @empty 数据为空提示... @endforelse 2. @foreach($data as $v) 循环数据内容... ...

  3. 关于js更改编码问题

    前言 前几天调试喜马拉雅的js加密算法,找到固定一段加密算法后调试,发现结果与实际不一致,后来发现是js显示的编码不一致,而我用的密钥是直接通过 chrome控制台复制下来的,这就导致最后结果不一致. ...

  4. js-day02-综合案例ATM存款书写

     <script>                 // 1. 不断的弹出对话框         // 3. 金额的变量         let money = 100         w ...

  5. 4.11:Storm之WordCount

    〇.概述 1.拓扑结构 2.目标 使用storm进行计数实验. 一.启动服务   在网页中输入:http://localhost:8081可以查看storm的相关信息. 二.kafka操作 终端中输入 ...

  6. 2.9:数据交换-csv、Excel、json、爬虫、Tushare获取数据

    〇.任务 1. 使用Python基础文件读写函数完成CSV文件的处理: 2. 使用标准CSV库完成CSV文件的处理: 3. 使用Excel库完成Excel文件的处理: 4. Python数据结构和Js ...

  7. 【Java SE进阶】Day05 异常,线程

    一.异常 1.概念 程序执行过程中,出现非正常情况导致JVM的非正常停止 本身是一个类,产生异常即创建并抛出一个异常对象 Java处理异常的方式是进行中断处理 异常非语法错误,语法错误直接不会产生cl ...

  8. 如何通过Java应用程序压缩PDF文档

    PDF文档是我们日常办公中使用最频繁的文档格式.但因为大多数PDF文档都包含很多页面图像或大量图片,这就导致PDF文档过大,处理起来较为麻烦.PDF文件过大,就会导致传输或者下载的速度变慢,也会增加传 ...

  9. 如何使用 System.Text.Json 序列化 DateTimeOffset 为 Unix 时间戳

    在 .NET 中,日期和时间通常使用 DateTime 或 DateTimeOffset 来表示.这两种数据类型都可以表示日期和时间,但它们之间有一些明显的区别.DateTime 是不带时区信息的,而 ...

  10. 【机器学习】李宏毅——Transformer

    Transformer具体就是属于Sequence-to-Sequence的模型,而且输出的向量的长度并不能够确定,应用场景如语音辨识.机器翻译,甚至是语音翻译等等,在文字上的话例如聊天机器人.文章摘 ...