当前位置: 首页 > article >正文

0903Redux改造项目_用户信息_状态管理-react-仿低代码平台项目

文章目录

    • 1 Redux管理用户信息
      • 1.1 定义store和reducer
      • 1.2 使用useSeletor
    • 2 自定义Hook统一加载用户信息存储Redux
    • 3 根据用户登录状态动态跳转页面
    • 结语

1 Redux管理用户信息

1.1 定义store和reducer

src/store/userReducer.ts代码如下所示:

import { createSlice, PayloadAction } from "@reduxjs/toolkit";export type UserStateType = {username: string;nickname: string;
};const INIT_STATE = {username: "",nickname: "",
};const userSlice = createSlice({name: "user",initialState: INIT_STATE,reducers: {loginReducer: (state: UserStateType,action: PayloadAction<UserStateType>) => {return action.payload;},logoutReducer: () => INIT_STATE,},
});export const { loginReducer, logoutReducer } = userSlice.actions;export default userSlice.reducer;

src/store/index.ts代码如下所示:

import { configureStore } from "@reduxjs/toolkit";
import userReducer, { UserStateType } from "./userReducer";export type StateType = {user: UserStateType
}export default configureStore({reducer: {// 分模块user: userReducer,},
});

main.tsx代码如下所示:

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
// import './index.css'
import App from "./App.tsx";
import store from "@/store";createRoot(document.getElementById("root")!).render(<StrictMode><Provider store={store}><App /></Provider></StrictMode>
);

1.2 使用useSeletor

获取用户信息hook useGetUserInfo.ts代码如下所示:

import { StateType } from "@/store";
import { UserStateType } from "@/store/userReducer";
import { useSelector } from "react-redux";function useGetUserInfo() {const { username, nickname } = useSelector<StateType>((state) => state.user) as UserStateType;return { username, nickname };
}export default useGetUserInfo;

用户信息页UserInfo.tsx代码如下所示:

import { FC } from "react";
import { Link, useNavigate } from "react-router-dom";
// import { useRequest } from "ahooks";
import { Button } from "antd";
import { UserOutlined } from "@ant-design/icons";import { LOGIN_PATHNAME } from "../router/index";
// import { getUserInfoApi } from "@/api/user";
import { removeToken } from "@/utils/userToken";
import useGetUserInfo from "@/hooks/useGetUserInfo";
import { useDispatch } from "react-redux";
import { logoutReducer } from "@/store/userReducer";const UserInfo: FC = () => {const nav = useNavigate();// const { data } = useRequest(getUserInfoApi);// const { username, nickname } = data || {};const { username, nickname } = useGetUserInfo();const dispatch = useDispatch();function logout() {// 清除用户信息和token信息dispatch(logoutReducer());removeToken();// 跳转登录页nav(LOGIN_PATHNAME);}const User = (<><span style={{ color: "#e8e8e8" }}><UserOutlined />{nickname}</span><Button type="link" onClick={logout}>退出</Button></>);const Login = <Link to={LOGIN_PATHNAME}>登录</Link>;return <>{username ? User : Login}</>;
};
export default UserInfo;

Logo.tsx页面在登录和不登录两种情况下,点击跳转不同页面,Logo.tsx代码如下所示:

import { FC, useEffect, useState } from "react";
import { Space, Typography } from "antd";
import { FormOutlined } from "@ant-design/icons";
import { Link } from "react-router-dom";
import styles from "./Logo.module.scss";
import useGetUserInfo from "@/hooks/useGetUserInfo";
import { LOGIN_PATHNAME } from "@/router";const { Title } = Typography;const Logo: FC = () => {const { username } = useGetUserInfo();const [pathname, setPathname] = useState("/");useEffect(() => {if (username) {setPathname(LOGIN_PATHNAME);  }}, [username]);return (<div className={styles.container}><Link to={pathname}><Space><Title><FormOutlined /></Title><Title>调查问卷</Title></Space></Link></div>);
};export default Logo;

2 自定义Hook统一加载用户信息存储Redux

加载用户信息是从后端获取用户数据,useLoadUserData.ts代码如下图所示:

import { useEffect, useState } from "react";
import { useRequest } from "ahooks";
import { useDispatch } from "react-redux";
import { loginReducer } from "@/store/userReducer";
import useGetUserInfo from "./useGetUserInfo";
import { getUserInfoApi } from "@/api/user";function useLoadUserData() {const [waitingUserData, setWaitingUserData] = useState(true);const dispatch = useDispatch();// ajax 加载用户信息const { run } = useRequest(getUserInfoApi, {manual: true,onSuccess(res) {const { username, nickname } = res;dispatch(loginReducer({ username, nickname }));},onFinally() {setWaitingUserData(false);},});// 判断redux是否已经存在用户信息const { username } = useGetUserInfo();useEffect(() => {if (username) {setWaitingUserData(false);return;}run();}, [username]);return { waitingUserData };
}export default useLoadUserData;

加载用户信息后存储在Redux

3 根据用户登录状态动态跳转页面

页面调整判定:

  • 用户已经登录,访问登录页或者注册页,需要跳转我的问卷页
  • 用户未登录,访问首页,登录页和注册页放行
  • 用户未登录,访问需要用户信息的页面,跳转登录页

自动以hook useNavPage.ts,代码如下所示:

import { useEffect } from "react";
import useGetUserInfo from "./useGetUserInfo";
import { useLocation, useNavigate } from "react-router-dom";
import {isLoginOrRegister,isNotNeedUserInfo,LOGIN_PATHNAME,MANAGE_INDEX_PATHNAME,
} from "@/router";function useNavPage(waitingUserData: boolean) {const { username } = useGetUserInfo();const { pathname } = useLocation();const nav = useNavigate();useEffect(() => {if (waitingUserData) {return;}// 已登录if (username) {if (isLoginOrRegister(pathname)) {console.log("url", pathname);// 不需要再登录或者注册nav(MANAGE_INDEX_PATHNAME);}return;}// 未登录if (isNotNeedUserInfo(pathname)) {// 不需要用户信息return;} else {nav(LOGIN_PATHNAME);}}, [waitingUserData, username, pathname]);
}export default useNavPage;

在MainLayout.tsx和QuestionLayout.tsx如下位置调用:

// ...
import useNavPage from "@/hooks/useNavPage";const { Header, Content, Footer } = Layout;
const MainLayout: FC = () => {const { waitingUserData } = useLoadUserData();useNavPage(waitingUserData)
// ....
};export default MainLayout;

结语

❓QQ:806797785

⭐️仓库地址:https://gitee.com/gaogzhen

⭐️仓库地址:https://github.com/gaogzhen

[1]react官网[CP/OL].

[2]Redux官网[CP/OL].

[3]Redux Toolkit官网[CP/OL].

相关文章:

0903Redux改造项目_用户信息_状态管理-react-仿低代码平台项目

文章目录 1 Redux管理用户信息1.1 定义store和reducer1.2 使用useSeletor 2 自定义Hook统一加载用户信息存储Redux3 根据用户登录状态动态跳转页面结语 1 Redux管理用户信息 1.1 定义store和reducer src/store/userReducer.ts代码如下所示&#xff1a; import { createSlice…...

LeapVAD:通过认知感知和 Dual-Process 思维实现自动驾驶飞跃——论文阅读

《LeapVAD: A Leap in Autonomous Driving via Cognitive Perception and Dual-Process Thinking》2025年1月发表&#xff0c;来自浙江大学、上海AI实验室、慕尼黑工大、同济大学和中科大的论文。 尽管自动驾驶技术取得了显著进步&#xff0c;但由于推理能力有限&#xff0c;数…...

windows 部署 Kafka3.x KRaft 模式 不依赖 ZooKeeper

1.下载 https://archive.apache.org/dist/kafka/3.9.0/kafka_2.12-3.9.0.tgz2.配置使用 KRaft 模式 2.1 修改 Kafka 的配置文件 cd D:\data\bigdata\kafka_2.12-3.9.0\config\kraft 修改 server.properties # 设置 Kafka 数据日志存储目录 log.dirsD:\\data\\bigdata\\kaf…...

Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析

注&#xff1a;本文为 “Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析” 相关文章合辑。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 Xilinx FPGA 管脚 XDC 约束之&#xff1a;物理约束 FPGA技术实战 于 2020-02-04 17:14:53 发布 说明&#x…...

Python-JsonRPC

Python-JsonRPC 使用Python学习JsonRPC数据交互 1-核心知识点 1&#xff09;什么是JsonRPC&#xff0c;这种协议是如何工作的&#xff1f;->使用请求进行验证2&#xff09;JsonRPC可以使用Postman进行验证吗&#xff1f;->可以使用POSTMAN进行调用&#xff08;使用HTTP请…...

Redis从入门到实战——实战篇(下)

四、达人探店 1. 发布探店笔记 探店笔记类似于点评网站的评价&#xff0c;往往是图文结合。对应的表有两个&#xff1a; tb_blog&#xff1a;探店笔记表&#xff0c;包含笔记中的标题、文字、图片等tb_blog_comments&#xff1a;其他用户对探店笔记的评价 步骤①&#xff1…...

面试问题(连载。。。。)

flexbox 和 crid 的区别 1. 布局维度与核心特性 Flexbox&#xff08;弹性盒子&#xff09; 一维布局&#xff1a;专注于行或列的线性排列&#xff0c;适合单方向&#xff08;水平或垂直&#xff09;的布局需求。动态分配空间&#xff1a;通过 flex-grow、flex-shrink 和 flex…...

springboot项目tomcat中加载不了

Spring Boot项目在Tomcat中加载不了的问题可能由多种原因引起&#xff0c;包括打包方式不正确、依赖配置错误、启动类配置不当等。以下是详细的解决方案&#xff1a; 1. 修改项目打包形式 将项目打包形式从jar改为war&#xff0c;以确保项目以正确的格式被Tomcat加载。在pom.…...

venv和pyenv在mac上

是的&#xff0c;理论上你可以用 venv 选择 Python 版本&#xff0c;但有一个关键前提&#xff1a;系统中必须已安装该版本的 Python 解释器。venv 本身并不提供 Python 版本管理功能&#xff0c;它只是基于现有的 Python 环境创建虚拟隔离空间。以下分场景详细说明&#xff1a…...

OpenCv实战笔记(1)在win11搭建opencv4.11.1 + qt5.15.2 + vs2019_x64开发环境

一. 准备工作 Visual Studio 2019&#xff08;安装时勾选 C 桌面开发 和 Windows 10 SDK&#xff09; CMake 3.20&#xff08;官网下载&#xff09; Qt 5.15.2&#xff08;下载 Qt Online Installer&#xff09;安装时勾选 MSVC 2019 64-bit 组件。 opencv 4.11.1 源码下载 git…...

前端获取流式数据并输出

在一些实时对话、日志推送等场景下&#xff0c;如果使用传统一次性加载数据的方式&#xff0c;可能会出现等待时间较长的不友好交互&#xff0c;这个时候我们需要使用流式布局分段获取数据&#xff0c;渐进式加载&#xff0c;减少等待焦虑。 原生js上&#xff0c;我们使用fetch…...

全局网络:重构数字时代的连接范式

从局部到全局 —— 网络架构的范式革命 在全球化与数字化深度融合的今天&#xff0c;传统网络架构的 “碎片化” 问题日益凸显&#xff1a;跨地域数据流通低效、设备互联孤岛化、安全策略难以统一。 全局网络作为一种突破地域与技术边界的新型网络架构&#xff0c;正成为企业…...

C++ Primer (第五版)-第十四章重载运算与类型转换

文章目录 一、基本概念可以被重载某些运算符不应被重载尽量明智使用运算符重载赋值和复合赋值运算符选择作为成员或者非成员 输入和输出运算符输入运算符尽量减少格式化操作输入输出运算符必须是非成员函数 重载输入运算符>>输入时的错误标示错误 算数和关系运算符相等运…...

nt!MiSessionAddProcess函数分析和nt!MmSessionSpace全局变量的关系

第一部分&#xff1a; 1: kd> g Breakpoint 42 hit nt!MiSessionAddProcess: 80ab2fbe 55 push ebp 1: kd> kc # 00 nt!MiSessionAddProcess 01 nt!MmCreateProcessAddressSpace 02 nt!PspCreateProcess 03 nt!NtCreateProcessEx 04 nt!_KiSystemServic…...

鸿蒙开发——5.ArkUI @Builder装饰器:打造高效可复用的UI组件

鸿蒙开发——5.ArkUI Builder装饰器&#xff1a;打造高效可复用的UI组件 ArkUI Builder装饰器&#xff1a;打造高效可复用的UI组件一、Builder装饰器是什么&#xff1f;二、两种构建函数类型1. 私有自定义构建函数2. 全局自定义构建函数 三、参数传递核心规则1. 按值传递&#…...

bash和zsh的区别

Bash&#xff08;Bourne-Again SHell&#xff09;和 Zsh&#xff08;Z Shell&#xff09;都是 Unix/Linux 系统中的主流 Shell&#xff0c;但它们在功能、配置和用户体验上有显著区别。以下是两者的详细对比&#xff1a; 1. 历史与兼容性 特性BashZsh诞生时间1989 年&#xff…...

PyTorchVideo实战:从零开始构建高效视频分类模型

视频理解作为机器学习的核心领域&#xff0c;为动作识别、视频摘要和监控等应用提供了技术基础。本教程将详细介绍如何利用PyTorchVideo和PyTorch Lightning两个强大框架&#xff0c;构建基于Kinetics数据集训练的3D ResNet模型&#xff0c;实现高效的视频分类流程。 PyTorch…...

深入理解Spring缓存注解:@Cacheable与@CacheEvict

在现代应用程序开发中&#xff0c;缓存是提升系统性能的重要手段。Spring框架提供了一套简洁而强大的缓存抽象&#xff0c;其中Cacheable和CacheEvict是两个最常用的注解。本文将深入探讨这两个注解的工作原理、使用场景以及最佳实践。 1. Cacheable注解 基本概念 Cacheable…...

Rust 与 Golang 深度对决:从语法到应用场景的全方位解析

一、引言 在软件开发的快速发展浪潮中&#xff0c;Rust 和 Golang&#xff08;Go 语言&#xff09;脱颖而出&#xff0c;成为开发者热议的编程语言。Rust 凭借强大的内存安全性与卓越的性能备受赞誉&#xff0c;Golang 则以简洁的语法和出色的并发处理能力赢得开发者青睐。本文…...

java加强 -泛型

概念 定义类、接口、方法时&#xff0c;同时声明了一个或多个类型变量&#xff08;如<E>&#xff09;&#xff0c;称为泛型类、泛型接口、泛型方法、它们统称为泛型。 语法 public class ArrayList<E>{} E可以接收不同类型的数据&#xff0c;可以是字符串&…...

pygame联网飞机大战游戏实现

客户端 import pygame import socket import json import threadingclass GameClient:def __init__(self):pygame.init()self.screen_width 600 # 宽度减小self.screen_height 800 # 高度增加self.screen pygame.display.set_mode((self.screen_width, self.screen_heigh…...

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(二)

8 行为规范 8.1 本章定义监督实体&#xff08;Supervisor&#xff09;与加工资源&#xff08;Processing Resource&#xff09;为实现物料加工所需的高层级通信逻辑&#xff0c;不涉及具体消息细节&#xff08;详见第10章消息服务&#xff09;。 8.2 加工任务通信 8.2.1 加工…...

根据窗口大小自动调整页面缩放比例,并保持居中显示

vue 项目 直接上代码 图片u1.png 是个背景图片 图片u2.png 是个遮罩 <template><div id"app"><div class"viewBox"><divclass"screen":style"{ transform: translate(-50%,-50%…...

如何在Jmeter中调用C程序?

在JMeter中调用C语言程序可以通过以下几种方式实现&#xff1a; 方法一&#xff1a;使用OS Process Sampler JMeter的“OS Process Sampler”可以用来调用外部程序&#xff0c;包括C语言编写的可执行文件。 步骤&#xff1a; 准备C语言程序&#xff1a; 编写C语言代码并编译…...

Android SDK 国内镜像及配置方法(2025最新,包好使!)

2025最新android sdk下载配置 1、首先你需要有android sdk manager2、 直接上教程修改hosts文件配置域名映射即可(不用FQ)2.1 获取ping dl.google.com域名ip地址2.2 配置hosts文件域名映射2.3 可以随意下载你需要的sdk3、 总结:走过弯路,踩过坑!!!大家就不要踩了!避坑1…...

【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现

&#x1f3b5; 【Python开源】深度解析&#xff1a;一款高效音频封面批量删除工具的设计与实现 &#x1f308; 个人主页&#xff1a;创客白泽 - CSDN博客 &#x1f525; 系列专栏&#xff1a;&#x1f40d;《Python开源项目实战》 &#x1f4a1; 热爱不止于代码&#xff0c;热情…...

OpenStack Yoga版安装笔记(26)实例元数据笔记

一、实例元数据概述 1.1 元数据 &#xff08;官方文档&#xff1a;Metadata — nova 25.2.2.dev5 documentation&#xff09; Nova 通过一种叫做元数据&#xff08;metadata&#xff09;的机制向其启动的实例提供配置信息。这些机制通常通过诸如 cloud-init 这样的初始化软件…...

【Linux】swap交换分区管理

目录 一、Swap 交换分区的功能 二、swap 交换分区的典型大小的设置 2.1 查看交换分区的大小 2.1.1 free 2.1.2 cat /proc/swaps 或 swapon -s 2.1.3 top 三、使用交换分区的整体流程 3.1 案例一 3.2 案例二 一、Swap 交换分区的功能 计算机运行一个程序首先会将外存&am…...

Spring IoC (Inversion of Control) 控制反转是什么?

我们分析一下 IoC (Inversion of Control) 控制反转的核心思想。 核心思想&#xff1a; IoC 是一种设计原则&#xff08;Design Principle&#xff09;&#xff0c;它描述了一种软件设计模式&#xff0c;其中组件&#xff08;对象&#xff09;的创建、依赖关系的管理和生命周…...

互联网大厂Java求职面试:核心技术点深度解析

互联网大厂Java求职面试&#xff1a;核心技术点深度解析 在互联网大厂的Java岗位面试中&#xff0c;技术总监级别的面试官通常会从实际业务场景出发&#xff0c;层层深入地考察候选人的技术能力。本文通过一个严肃专业的技术总监与搞笑但有技术潜力的程序员郑薪苦之间的互动对…...