【react+redux】 react使用redux相关内容

ops/2025/2/3 2:40:51/

首先说一下,文章中所提及的内容都是我自己的个人理解,是我理逻辑的时候,自我说服的方式,如果有问题有补充欢迎在评论区指出。

一、场景描述

为什么在react里面要使用redux,我的理解是因为想要使组件之间的通信更便捷。如下图所示,html中的信息传递只能是通过标签属性来传递,所以如果
我们有一个需求是在某一个组件中获取信息,然后在另一个组件中根据该信息来更改组件显示的内容,这就需要逐层进行信息传递。redux的作用就在于,将该信息保存为全局数据内容,这样所有组件都可以访问到,不用逐层进行信息传递。
在这里插入图片描述

二、相关内容介绍

2.1 typescript中的函数调用签名

函数调用签名的作用是什么:定义函数所接收到参数以及返回值的类型。

type addFunctionType = (a: number, b: number) => number;
//这里是函数调用参数,上面定义了所接收参数以及返回值的类型。
const add: addFunctionType = (a, b) => a + b;
export default add;

2.2 问题分析

首先’react-redux’包里的useSelector用于从redux store中获取state的值,在使用该方法时,它的用法如下。

import {useSelector} from ‘react-redux’;
//问题就出在这里,如果用原始的函数这里的state就要对他进行类型声明—用any也可以,减少any的使用可以对代码有一定的收益,例如减少bug
const user = useSelector( state:any => state.user);

然后我们就希望拿到这个state的类型,state就是redux中的store.getstate所获得的数据
解释一下下面所要用到的一小段代码。

type IRootType = typeof store.getState;    //取store.getState这个函数的类型
//为什么不是 type IRootType = typeof store.getState(); 
export type FnReturnType = ReturnType<IRootType>;
//函数调用签名 它的作用是定义一个函数类型,包含函数的参数和返回类型
export const useAppSelector: TypedUseSelectorHook<FnReturnType> = useSelector;

在上述代码中我们所得到的store.getState的类型如下图所示。这个函数是用来获取state参数的,它的返回值应该是个对象,是store中所存储的全局变量–redux中存的数据。
在这里插入图片描述
react-redux中useSelector的作用是从redux store中获取state的值。跟直接获取的区别在于:当store中的值发生改变时,会自动渲染组件。
TypedUseSelectorHook的实现如下图所示

interface TypedUseSelectorHook<TState> {//这里的<Tselected>是传入类型的意思,在后面所输入的第一个函数参数里使用 两个参数一个是selector,接收TState 类型的参数,输出Tselected类型的变量<TSelected>(selector: (state: TState) => TSelected,equalityFn?: EqualityFn<NoInfer<TSelected>>): TSelected;<Selected = unknown>(selector: (state: TState) => Selected,options?: UseSelectorOptions<Selected>): Selected;
}

在这里插入图片描述

2.3上述内容总结

请添加图片描述

二、redux相关内容

在介绍redux的内容之前,我们先分析一下需求,一般如果是这样的话,就是在所有组件都能访问到的区域创建数据。

2.1 redux的工作原理

redux的工作原理如下图所示。
图中Store是Redux的一个对象,用于保存应用的状态。–这里就是用于存储全局数据的地方,不能直接更改可以读,需要提供特征的方法进行更改。
Action就是所定义的动作类型,可以包含其他属性,用于传递额外的数据。我的理解就是定义的行为,存储的全局数据可以发生的行为需要提前定义,实际上就是定义的方法。
Reducers:就是根据Action来更新当前的State(全局数据,在react中被定义为状态)。
Dispatch: 用于向Store中发送Action。当调用store.dispatch(action)时,Store会调用reducer来处理action,更新state。
subcribe:注册监听器,当state发生变化的时候,监听器被使用。
在这里插入图片描述

2.2原生redux的使用

原生redux在我看来,他就是解决了一个提供所有组件全局变量的一个方案,数据改变之后他还是需要进行手动渲染。react中如果state或者props变化,他就会自动重新渲染组件,所以我们使用的方案是使用一个key state当你变化一次的时候,我们就让key变化一次,导致其重新渲染。
store.ts

import { legacy_createStore as createStore } from "redux";const reducer = (state, action) => {if (action.type === "increment") {state.num += 1;} else if (action.type === "decrement") {state.num -= 1;} else if (action.type === "incrementByAmount") {state.num += action.payload;} else if (action.type === "change") {state.amount = action.payload;}return state;
};const store = createStore(reducer, {num: 0,amount: 1,
});store.subscribe(() => {console.log("数据发生了变化");
});export default store;

app.tsx

import React, { useState } from "react";
import store from "./js/store";
function App() {let [key, setKey] = useState(1);let dispatch = store.dispatch;return (<div className="App"><h2>测试redux页面</h2><br /><br /><buttononClick={() => {dispatch({ type: "increment" });setKey(key + 1);}}>Increment</button><span>{store.getState().num}</span>   <buttononClick={() => {dispatch({ type: "decrement" });setKey(key + 1);}}>Decrement</button><br /><inputtype="text"value={store.getState().amount}onChange={(e) => {dispatch({ type: "change", payload: parseInt(e.target.value) });setKey(key + 1);}}/><buttononClick={() => {dispatch({type: "incrementByAmount",payload: store.getState().amount,});setKey(key + 1);}}>incrementByAmount</button></div>);
}export default App;

三、@reduxjs/toolkit与react-redux的相关内容

原生react在每一个使用stroe的组件文件中都要引用一次store文件,觉得很麻烦,react-redux提供了Provider组件使其只需要引用一次,使得redux更便捷。
index.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";//redux的相关内容导入
import { Provider } from "react-redux";
import store from "./app/store";
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement
);
root.render(<Provider store={store}><BrowserRouter><App /></BrowserRouter></Provider>
);

在@reduxjs/toolkit工具中,它将initialState、reducer以及actions整合在一起形成切片,更符合传统编程类的概念。
countSlice.ts

import { createSlice } from "@reduxjs/toolkit";export const counterSlice = createSlice({// 定义切片名name: "counter",// 定义切片中的全局变量initialState: {value: 0,},// reducer处理器reducers: {increment: (state) => {console.log(state);state.value += 1;},decrement: (state) => {state.value -= 1;},incrementByAmount: (state, action) => {console.log(action);state.value += action.payload;},},
});// 生成action
export const { increment, decrement, incrementByAmount } = counterSlice.actions;export default counterSlice.reducer;

TestRedux.tsx

import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import {decrement,increment,incrementByAmount,
} from "../features/counter/counterSlice";export default function TestRedux() {// 获取变量const count = useSelector((state: any) => state.counter.value);// 处理actionconst dispatch = useDispatch();const [amount, setAmount] = useState(1);return (<div><h2>测试redux页面</h2><br /><br /><button onClick={() => dispatch(increment())}>Increment</button><span>{count}</span>   <button onClick={() => dispatch(decrement())}>Decrement</button><br /><inputtype="text"value={amount}onChange={(e) => {setAmount(parseInt(e.target.value));}}/><button onClick={() => dispatch(incrementByAmount(amount))}>Decrement</button></div>);
}

在这里插入图片描述


http://www.ppmy.cn/ops/155195.html

相关文章

双层Git管理项目,github托管显示正常

双层Git管理项目&#xff0c;github托管显示正常 背景 在写React项目时&#xff0c;使用Next.js,该项目默认由git托管。但是我有在项目代码外层记笔记的习惯&#xff0c;我就在外层使用了git托管。 目录如下 code 层内也有.git 文件&#xff0c;对其托管。 我没太在意&…

日志2025.2.1

日志2025.2.1 1.做了敌人状态机 public class EnermyStateMachine { public EnermyState currentState { get; private set; } public void InitializeState(EnermyState startState) { currentState startState; currentState.Enter(); } public void Change…

C#面向对象(封装)

1.什么是封装? C# 封装 封装 被定义为“把一个或多个项目封闭在一个物理的或者逻辑的包中”。 在面向对象程序设计方法论中&#xff0c;封装是为了防止对实现细节的访问。 抽象和封装是面向对象程序设计的相关特性。 抽象允许相关信息可视化&#xff0c;封装则使开发者实现所…

Python之Excel操作 - 读取数据

我们将使用 openpyxl 库&#xff0c;它是一个功能强大且易于使用的库&#xff0c;专门用于处理 Excel 文件。 1. 安装 openpyxl 首先&#xff0c;你需要安装 openpyxl 库。你可以使用 pip 命令进行安装&#xff1a; pip install openpyxl2. 读取 Excel 文件 要读取 Excel 文…

conda配置channel

你收到 CondaKeyError: channels: value https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main not present in config 错误是因为该镜像源&#xff08;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main&#xff09;可能没有被正确添加到 Conda 的配置文件中&…

Flink Connector 写入 Iceberg 流程源码解析_confluent icebergsinkconnector

// 添加 Writer 算子&#xff0c;有并行度SingleOutputStreamOperator<WriteResult> writerStream appendWriter(distributeStream, flinkRowType, equalityFieldIds);// 添加 Commit 算子&#xff0c;并行度固定为 1 SingleOutputStreamOperator<Void> committerS…

深入理解若依RuoYi-Vue数据字典设计与实现

深入理解若依数据字典设计与实现 一、Vue2版本主要文件目录 组件目录src/components&#xff1a;数据字典组件、字典标签组件 工具目录src/utils&#xff1a;字典工具类 store目录src/store&#xff1a;字典数据 main.js&#xff1a;字典数据初始化 页面使用字典例子&#xf…

“开源AI智能名片2+1链动模式S2B2C商城小程序源码”在市场推广中的应用与策略

摘要&#xff1a;本文旨在探讨“开源AI智能名片21链动模式S2B2C商城小程序源码”在市场推广中的应用策略。通过分析品牌与企业实力的展示、产品体验分享以及赋能B端合作伙伴的重要性&#xff0c;本文提出了一套系统的市场推广方案。该方案强调以信任为基础&#xff0c;以自用体…