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

embedded/2024/9/23 9:09:01/

目标

学会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/embedded/24604.html

相关文章

拆单算法交易(Algorithmic Trading)

TWAP TWAP交易时间加权平均价格Time Weighted Average Price 模型&#xff0c;是把一个母单的数量平均地分配到一个交易时段上。该模型将交易时间进行均匀分割&#xff0c;并在每个分割节点上将拆分的订单进行提交。例如&#xff0c;可以将某个交易日的交易时间平均分为N 段&am…

web server apache tomcat11-23-APR

前言 整理这个官方翻译的系列&#xff0c;原因是网上大部分的 tomcat 版本比较旧&#xff0c;此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎&#xff0c;轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

数据污染对大型语言模型的潜在影响

大型语言模型&#xff08;LLMs&#xff09;中存在的数据污染是一个重要问题&#xff0c;可能会影响它们在各种任务中的表现。这指的是LLMs的训练数据中包含了来自下游任务的测试数据。解决数据污染问题至关重要&#xff0c;因为它可能导致结果偏倚&#xff0c;并影响LLMs在其他…

Blender曲线操作

1.几种常见建模方式 -多边形建模&#xff1a;Blender&#xff0c;C4D&#xff0c;3DsMax&#xff0c;MaYa -曲线&#xff1a; -曲面&#xff1a;Rhino&#xff08;Nurbs&#xff09; -雕刻&#xff1a;Blender&#xff0c;ZBrush -蜡笔&#xff1a;Blender 1&#xff09;新…

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(二)

探索和构建 LLaMA 3 架构&#xff1a;深入探讨组件、编码和推理技术&#xff08;二&#xff09; RoPE&#xff08;旋转位置编码&#xff09; 在深入研究 RoPE 之前&#xff0c;了解绝对位置编码和相对编码之间的区别非常重要。 绝对位置编码是添加到标记嵌入中以表示其在句子…

Django加载静态文件出错‘staticfiles‘ is not a registered tag library.

在html文件中输入{% load staticfiles %}&#xff0c;提示错误信息&#xff1a;staticfiles is not a registered tag library. 解决&#xff1a; 在 Django 中&#xff0c;如果要加载静态文件&#xff0c;应该使用 {% load static %} 而不是 {% load staticfiles %}。static…

深度学习模型Deep Learning Model

什么是深度学习&#xff1f;&#xff1f; 深度学习模型是一种基于人工神经网络&#xff08;Artificial Neural Networks, ANN&#xff09;的机器学习模型&#xff0c;其核心思想是通过多层次的神经网络结构来学习数据的特征表示和模式。这些模型通常由多个层次&#xff08;深度…

idea自定义配置文件的注释

打开 IntelliJ Idea 软件 依次找到 File—>Editor—>File and Code Templates 设置 Files 下的Class、Interface、Enum等 输入下面的内容 /** * description: ${NAME} * date: ${YEAR}-${MONTH}-${DAY} ${HOUR}:${MINUTE} * author: author **/