React + 项目(从基础到实战) -- 第十期

news/2024/9/24 3:27:05/

目标

学会react 状态管理工具
使用redux管理用户状态

Context

  1. 跨层级传递,不像props层层传递
  2. 类似于Vue的provide/inject
  3. 用于:切换主题颜色,切换语言

useReducer

useState 的替代方案
简化版的redux

MobX

1. MobX 介绍 · MobX 中文文档

声明式的修改数据 , 像vue
state
action
derivation 派生: computed observer

Redux

  • state/store (存储的数据)
  • action(发布的命令 类似导航让我们知道发生了什么)
  • reducer(生成新的state 联系起state与action)
  • dispatch(派发的action,产生数据)

默认支持跨组件通讯

redux_36">项目实战–redux

快速开始 | Redux 中文官网

Redux 要求我们通过创建数据副本和更新数据副本,来实现不可变地写入所有状态更新。不过 Redux Toolkit createSlice 和 createReducer 在内部使用 Immer 允许我们编写“可变”的更新逻辑,变成正确的不可变更新。

redux_41">引入redux

安装

npm install @reduxjs/toolkit react-redux

为 React 提供 Redux Store

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

创建Redux Store

import { configureStore } from '@reduxjs/toolkit'import userReducer from './userReducer'export default configureStore({reducer: {//分模块注册user: userReducer, // 注册userReducer// 你可以在这里注册更多的reducer}})

创建 Redux State Slice

import { createSlice , PayloadAction } from "@reduxjs/toolkit";export type UserStateType={username:string,nickname:string}const INIT_STATE:UserStateType={username:"",nickname:""}export const userSlice=createSlice({name:"user",initialState:INIT_STATE,reducers:{//登录保存用户信息loginReducer:(state,action:PayloadAction<UserStateType>)=>{return action.payload // 设置username nickname 到 redux store//用不到immer},//退出删除用户信息logoutReducer:()=>{return INIT_STATE // 设置username nickname 到 redux store//用不到immer}}})export const {loginReducer,logoutReducer}=userSlice.actionsexport default userSlice.reducer

使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用户信息存储

自定义hook

import { useEffect , useState } from "react";import { useRequest } from "ahooks";//导入发起请求的函数import { useDispatch } from "react-redux";import { getUserInfoService } from "../services/user";import { loginReducer } from "../store/userReducer";import useGetUserInfo from "./useGetUserInfo";function useLoadUserData() {const dispatch = useDispatch();const [waitingUserData , setWaitingUserData] = useState(true);//ajax 加载用户信息const {run } = useRequest(getUserInfoService , {manual:true,onSuccess: (data) => {const {username , nickname} = data;dispatch(loginReducer({username,nickname})) // 存储到redux store},onFinally(){setWaitingUserData(false);}})//判断当前的redux  store 是否存在用户信息const {username} = useGetUserInfo()useEffect(() => {if(username){setWaitingUserData(false); // redux中存在信息,则不用重新加载return ;}run();// 如果不存在,则进行加载},[username])return {waitingUserData};}export default useLoadUserData;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于后端有延迟,首页闪了一下,前端使用spin组件(显示加载效果)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

bug :用户登录成功后.还能访问登录注册页

预期效果:
已经登录
1. 跳转页面是登录注册页 , 重定向到我的问卷
2. 跳转页面不是登录注册页,放行
未登录
1. 跳转页面需要用户信息,重定向到登录页
2. 跳转页面不需要用户信息,放行

自定义hook

import React , {FC, useEffect} from "react";import useGetUserInfo from "./useGetUserInfo";import { useNavigate ,useLocation } from "react-router-dom";import useLoadUserData from "./useLoadUserData";import { isLoginOrRegiter, isNeedUserInfo, LOGIN_PATH, MANAGE_PATH } from "../router";function useNavPage() {const {waitingUserData} = useLoadUserData();const {username} = useGetUserInfo();const {pathname} = useLocation();const nav = useNavigate();useEffect(()=>{if(waitingUserData) return ;//已经登录了if(username){//跳转的页面是login/registerif(isLoginOrRegiter(pathname)){nav(MANAGE_PATH)}return}//没有登录if(isNeedUserInfo(pathname)){nav(LOGIN_PATH);}},[username,pathname])}export default useNavPage;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结

自定义hook使用
useGetUserInfo
useLoadUserData
useNavPage


http://www.ppmy.cn/news/1449362.html

相关文章

[蓝桥杯2024]-PWN:fd解析(命令符转义,标准输出重定向,利用system(‘$0‘)获取shell权限)

查看保护 查看ida 这里有一次栈溢出&#xff0c;并且题目给了我们system函数。 这里的知识点没有那么复杂 方法一&#xff08;命令转义&#xff09;&#xff1a; 完整exp&#xff1a; from pwn import* pprocess(./pwn) pop_rdi0x400933 info0x601090 system0x400778payloa…

Redis运维篇-快速面试笔记(速成版)

文章目录 1. Redis的持久化1.1 RDB&#xff08;快照模式&#xff09;1.2 AOF 模式 2. Redis主从模型&#xff08;高可用&#xff09;2.1 Redis的主从复制2.2 Redis拓扑结构 3. Redis集群模式&#xff08;高并发&#xff09;3.1 Redis的Slots3.2 集群模式的常用命令3.3 多主多从…

什么是HTTP?

什么是HTTP&#xff1f; HTTP基本概念HTTP 是什么&#xff1f;HTTP 常见的状态码有哪些&#xff1f;HTTP 常见字段有哪些&#xff1f; HTTP特性HTTP/1.1 的优点有哪些&#xff1f;HTTP/1.1 的缺点有哪些&#xff1f; HTTP基本概念 HTTP 是什么&#xff1f; HTTP 是超文本传输…

Java使用POI库对excel进行操作

excel转为图片 这个操作是要根据excel一行一行画出来的 package com.gxuwz.zjh.util;import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.…

【项目经验】Redis Sentinel从工程中下线并对业务迁移-(二)

在上篇文章【项目经验】Redis Sentinel从工程中下线并对业务迁移-进行中-CSDN博客有说到迁移的计划。最近一直按照计划进行迁移&#xff0c;期间遇到了不少问题。总结如下&#xff1a; 一、key未设置过期时间 redis基于内存存储&#xff0c;主要作用是缓存。当大量的key未设置…

Linux下启动jenkins报错问题解决

jenkins端口报错 java.io.IOException: Failed to start Jettyat winstone.Launcher.<init>(Launcher.java:209)at winstone.Launcher.main(Launcher.java:496)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.int…

Docker与Linux容器:“探索容器化技术的奥秘”

目录 一、Docker概述 二、容器技术的起源&#xff1a; 三、Linux容器 四、Docker的出现 五、Docker容器特点&#xff1a; 六、Docker三大概念&#xff1a; 容器&#xff1a; 镜像&#xff1a; 仓库&#xff1a; 七、Docker容器常用命令 一、Docker概述 在云原生时代&…

手动实现简易版RPC(三)

手动实现简易版RPC(三) 往期内容 手动实现简易版RPC&#xff08;一&#xff09;&#xff1a;RPC简介及系统架构 手动实现简易版RPC&#xff08;二&#xff09;&#xff1a;简单RPC框架实现 前言 接上两篇博客我们实现了最简易RPC框架&#xff0c;接下来的几期重点在简易版…