建设网站观澜/优化设计六年级下册语文答案

建设网站观澜,优化设计六年级下册语文答案,施工企业会计制度2022,烟台怎么做网站1.安装插件 这里的redux-persist--进行数据的持久化缓存,确保页面刷新数据不会丢失 yarn add react-redux^9.2.0 redux-persist^6.0.0 reduxjs/toolkit^2.5.1 2.创建仓库文件夹 在项目的src文件夹下创建名为store的文件夹,里面的具体文件如下 featur…

1.安装插件

这里的redux-persist--进行数据的持久化缓存,确保页面刷新数据不会丢失

yarn add react-redux@^9.2.0 redux-persist@^6.0.0 @reduxjs/toolkit@^2.5.1

2.创建仓库文件夹

在项目的src文件夹下创建名为store的文件夹,里面的具体文件如下

features文件夹对应文件如下

features文件夹中存放对应的需要进行状态管理的数据

couterSlice.ts

这里是一个简单的计数器的加减,赋值,清零的一个测试仓库

createSlice中包含的字段

initialState存储的字段

reducers对应useDispatch的分发行为

name仓库的唯一标识

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "../store";// 为 slice state 定义一个类型
interface CounterState {value: number;
}// 使用该类型定义初始 state
const initialState: CounterState = {value: 0,
};export const counterSlice = createSlice({name: "counter",// `createSlice` 将从 `initialState` 参数推断 state 类型initialState,reducers: {increment: (state) => {state.value += 1;},decrement: (state) => {state.value -= 1;},// 使用 PayloadAction 类型声明 `action.payload` 的内容,用于登录,注册等传入具体的参数incrementByAmount: (state, action: PayloadAction<number>) => {state.value += action.payload;},//清零emptyCount: (state, action: PayloadAction<number>) => {state.value = action.payload;},},
});export const { increment, decrement, incrementByAmount, emptyCount } =counterSlice.actions;
// 选择器等其他代码可以使用导入的 `RootState` 类型
export const selectCount = (state: RootState) => state.counter.value;export default counterSlice.reducer;
user.ts

存储用户信息以及模拟登录token的reducer

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "../store";
import {getToken,setToken,getLocal,setLocal,removeToken,removeLocal,
} from "@/utils/token";
import { Local } from "@/enums/Local";interface UserState {token: string | undefined | null;username: string | undefined | null;
}const initialState: UserState = {token: getToken() || undefined,username: getLocal(Local.USER_INFO)?.username || undefined,
};export const userSlice = createSlice({name: "user",initialState,reducers: {setInfo: (state, action: PayloadAction<UserState>) => {state.token = action.payload.token;state.username = action.payload.username;setToken(action.payload.token);setLocal(Local.USER_INFO, { username: action.payload.username });},remove: (state) => {state.token = undefined;state.username = undefined;removeToken();removeLocal(Local.USER_INFO);},},
});export const { setInfo, remove } = userSlice.actions;
// 选择器等其他代码可以使用导入的 `RootState` 类型
export const selectUser = (state: RootState) => state.user;export default userSlice.reducer;

user.ts文件夹下使用了一些方法,补充如下

utils文件夹下的token.ts文件 以及enums文件夹下的Loacl文件如下
import { Local } from "@/enums/Local";
/*** @Description: 生成一个随机token* @Date: 2024-11-20 17:14:19*/
export function generateToken(length: number) {const characters ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let token = "";for (let i = 0; i < length; i++) {const randomIndex = Math.floor(Math.random() * characters.length);token += characters[randomIndex];}return token;
}/*** @Description: 将token存储到localStorage中* @Date: 2024-11-20 17:15:12*/
export function setToken(token: string) {const expireTime = new Date().getTime() + 24 * 60 * 60 * 1000; // 设置当前时间加上24小时为过期时间const data = {token: token,expire: expireTime,};localStorage.setItem("token", JSON.stringify(data));
}/*** @Description: 从localStorage中获取token* @Date: 2024-11-20 17:15:42*/
export function getToken() {const dataString = localStorage.getItem("token");if (dataString) {const data = JSON.parse(dataString);const currentTime = new Date().getTime();if (currentTime > data.expire) {// 如果过期,则删除tokenremoveToken();return null; // token已过期,返回null}return data.token; // 返回有效的token}return null; // 如果没有token,返回null
}/*** @Description: 将localStorage中的token删除* @Date: 2024-11-20 17:16:02*/
export function removeToken() {localStorage.removeItem("token"); // 删除token
}/*** @Description: 设置本地存储* @Date: 2024-12-05 14:16:45*/
export function setLocal(key: Local, value: any) {localStorage.setItem(key, JSON.stringify(value));
}/*** @Description: 获取本地存储* @Date: 2024-12-05 14:19:02*/
export function getLocal(key: Local) {const dataString = localStorage.getItem(key);if (dataString) {console.log(JSON.parse(dataString));return JSON.parse(dataString);} else {return null;}
}/*** @Description: 清除本地存储* @Date: 2024-12-05 14:19:48*/
export function removeLocal(key: Local) {localStorage.removeItem(key);
}
export enum Local {USER_INFO = "USER_INFO",REDIRECT_PATH = "redirectPath",
}

hook.d.ts

定义这个声明文件,允许将它们导入到任何需要使用的 hooks 的组件文件中,并避免潜在的循环导入的依赖问题。

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'// 在整个应用程序中使用,而不是简单的 `useDispatch` 和 `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

store.ts仓库入口文件如下

使用persistConfig进行持久化配置,root为存储到本地的名称,没有特别的要求,whiteList白名单,存放的是需要持久化存储的仓库blackList则相反

import { configureStore } from "@reduxjs/toolkit";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage"; // 默认使用 localStorage
import counterReducer from "./features/couterSlice";
import userReducer from "./features/user";
// ...// 持久化配置
const persistConfig = {key: "root", // 存储的键名storage, // 存储方式whitelist: ["user"], // 需要持久化的reducerblacklist: ["counter"], // 不需要持久化的reducer
};const persistedReducer = persistReducer(persistConfig, userReducer);const store = configureStore({reducer: {counter: counterReducer,user: persistedReducer,},middleware: (getDefaultMiddleware) =>getDefaultMiddleware({serializableCheck: {// 忽略 redux-persist 的持久化 actionignoredActions: ["persist/PERSIST", "persist/REHYDRATE"],},}),
});const persistor = persistStore(store);// 从 store 本身推断出 `RootState` 和 `AppDispatch` 类型
export type RootState = ReturnType<typeof store.getState>;
// 推断出类型: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;export { store, persistor };

在入口文件main.tsx引入store.ts并配置

采取provider上下文的方式实现 数据的传输 使用PersistGate组件对白名单中的reducer进行持久化存储

import { createRoot } from "react-dom/client";
import "./index.css";
import { HashRouter } from "react-router-dom";
import App from "./App.tsx";
import { store, persistor } from "./store/store.ts";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";createRoot(document.getElementById("root")!).render(<HashRouter><Provider store={store}><PersistGate loading={null} persistor={persistor}><App /></PersistGate></Provider></HashRouter>
);

3.使用仓库

通过useSelector从redux的state中读取对应的值

useSelector((state: any) => state?.'仓库名称'.value)

useDispatch ,用于在组件中分发操作(action),从而更新 Redux store 中的数据。

从对应的reducer中引入对应的分发操作,因为reduxjs/toolkit的特性,再进行传参赋值的时候,不必要再像老版本一样{...旧值,新值}

传参赋值参考emptyCount这一函数等

使用conuterSlice仓库
import { useSelector, useDispatch } from "react-redux";
import {decrement,increment,incrementByAmount,emptyCount,
} from "@/store/features/couterSlice";
import { setInfo, remove } from "@/store/features/user";
import { Button } from "antd";function DefaultPage() {const count = useSelector((state: any) => state?.counter.value);const userInfo = useSelector((state: any) => state?.user);const dispatch = useDispatch();return (<><div><div><ButtonclassName="mr-4"onClick={() => dispatch(emptyCount(0))}type="primary">清零</Button><Button type="primary" onClick={() => dispatch(increment())}>increment增加</Button><div className="mt-2 mb-2">{count}</div><Buttontype="primary"className="mr-4"onClick={() => dispatch(decrement())}>Decrement减少</Button><Buttontype="primary"onClick={() => dispatch(incrementByAmount(count > 0 ? count : 1))}>增加指定值</Button></div></div></>);
}export default DefaultPage;
补充:结合user.ts这一reducer实现鉴权登录。

这里需要封装一个鉴权组件判断是否登录,给需要鉴权登录的组件嵌套上即可

import React from "react";
import { Local } from "@/enums/Local";
import { setLocal } from "@/utils/token";
import { Navigate, useLocation, useNavigate } from "react-router-dom";
import { useSelector } from "react-redux"; // 假设你使用 Redux// 这是一个路由守卫组件,用于检查用户是否登录
const RequireAuth = ({ children }: { children: React.ReactNode }) => {const location = useLocation();const userInfo = useSelector((state: any) => state?.user);// 如果用户未登录,则保存当前路径并重定向到登录页面if (!userInfo?.token) {setLocal(Local.REDIRECT_PATH, location.pathname);return <Navigate to="/login" />;}return children;
};export default RequireAuth;
登录页面

这里在用户名密码都正确后 采用useDispatch调用reducer中的serInfo方法 将用户名和token存储到storage 和 仓库中去,登录成功后重定向到第一次访问的默认页

import { Button, Checkbox, Form, Input, message } from "antd";
import { Local } from "@/enums/Local";
import { generateToken, getLocal, removeLocal } from "@/utils/token";
import { setInfo } from "@/store/features/user";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import type { FormProps } from "antd";
import "./index.less";function Login() {const [messageApi, contextHolder] = message.useMessage();const myCleft = "c_left";const myCright = "c_right";const userList = [{userName: "admin",password: "123456",},{userName: "student",password: "123456",},
];type FieldType = {username?: string;password?: string;};const dispatch = useDispatch();const navigate = useNavigate();const onFinish: FormProps<FieldType>["onFinish"] = (values) => {console.log("Success:", values);checkInfo(values);};const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {console.log("Failed:", errorInfo);};//判断用户名密码是否正确const checkInfo = (value: FieldType) => {//用户名const userIndex = userList.findIndex((item) => item.userName == value.username);if (userIndex == -1) {messageApi.open({type: "error",content: "用户名错误",duration: 1,});return;} else {const passwordIndex = userList.findIndex((item) => item.password == value.password);if (passwordIndex == -1) {messageApi.open({type: "error",content: "密码错误",duration: 1,});} else {messageApi.open({type: "loading",content: "登录中",duration: 1.5,}).then(() => {messageApi.open({type: "success",content: "登录成功",duration: 1,}).then(() => {handleLogin(value);});});}}};//登录const handleLogin = (value: FieldType) => {const token = generateToken(16);dispatch(setInfo({ token, username: value.username }));// 登录成功后const redirectPath = getLocal(Local.REDIRECT_PATH) || "/";removeLocal(Local.REDIRECT_PATH); // 清除路径navigate(redirectPath, { replace: true }); // 重定向};return (<>{contextHolder}<div className="w-full h-full " style={{ background: "lightgray" }}><div className="w-full h-full flex justify-center items-center"><div className="l_container"><div className="c_left"><div className={`${myCleft}-title`}>欢迎您的到来!</div><div className={`${myCleft}-title`}>WELCOME !</div><div className={`${myCleft}-desc`}>请在右侧输入账号密码,登录您的账号</div></div><div className="c_right"><div className={`${myCright}-title`}>请输入信息!</div><div className={`${myCright}-form`}><Formname="basic"labelCol={{ span: 8 }}wrapperCol={{ span: 16 }}style={{ maxWidth: 600 }}initialValues={{ remember: true }}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off"><Form.Item<FieldType>label="用户名:"name="username"rules={[{required: true,message: "请输入用户名称!",},]}><Input /></Form.Item><Form.Item<FieldType>label="密码:"name="password"rules={[{required: true,message: "请输入密码!",},]}><Input.Password /></Form.Item><Form.Item label={null}><ButtonclassName="sub_btn"type="primary"size="large"htmlType="submit">登录</Button></Form.Item></Form></div></div></div></div></div></>);
}export default Login;

参考git地址如下:

myReactRouterOnlyRead: 仅供参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TrustRAG:通过配置化模块化的检索增强生成(RAG)框架提高生成结果的可靠性和可追溯性

TrustRAG旨在风险感知的信息检索场景中提高生成内容的一致性和可信度。用户可以利用私有语料库构建自己的RAG应用程序&#xff0c;研究库中的RAG组件&#xff0c;并使用定制模块进行实验。论文展示了TrustRAG系统在摘要问答任务中的应用&#xff0c;并通过案例研究验证了其有效…

力扣27.移除元素(双指针)

题目看起来很乱&#xff0c;实际上意思是&#xff1a;把数组中值不等于val的元素放在下标为0,1,2,3......&#xff0c;并且返回数组中值不等于val的元素的个数 方法一&#xff1a;直接判断覆盖 class Solution { public:int removeElement(vector<int>& nums, int…

特辣的海藻!7

特邀嘉宾&#xff1a;滑动窗口~ 题 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 做过的题&#xff0c;再一次做&#xff0c;还是有问题。。。。我把它给解决掉&#xff01; 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 超时 …

not support ClassForName

com.alibaba.fastjson2.JSONException: not support ClassForName : java.lang.String, you can config JSONReader.Feature.SupportClassForName 官方说明中提到默认关闭&#xff0c; 可通过配置开启 JSON.config(JSONReader.Feature.SupportClassForName);

在VSCode 中使用通义灵码最新版详细教程

在 VSCode 中使用通义灵码&#xff1a;最新版详细教程与使用场景 Visual Studio Code&#xff08;简称 VSCode&#xff09;是一款由微软开发的轻量级、功能强大的开源代码编辑器&#xff0c;支持多种编程语言&#xff0c;深受开发者喜爱。而通义灵码&#xff08;TONGYI Lingma…

不要升级,Flutter Debug 在 iOS 18.4 beta 无法运行,提示 mprotect failed: Permission denied

近期如果有开发者的 iOS 真机升级到 18.4 beta&#xff0c;大概率会发现在 debug 运行时会有 Permission denied 的相关错误提示&#xff0c;其实从 log 可以很直观看出来&#xff0c;就是 Dart VM 在初始化时&#xff0c;对内核文件「解释运行&#xff08;JIT&#xff09;」时…

数据结构:反射 和 枚举

目录 一、反射 1、定义 2、反射相关的类 3、Class类 &#xff08;2&#xff09;常用获得类中属性相关的方法&#xff1a; &#xff08;3&#xff09;获得类中注解相关的方法&#xff1a; &#xff08;4&#xff09;获得类中构造器相关的方法&#xff1a; &#xff08;…

基于Electron的应用程序安全测试基础 — 提取和分析.asar文件的案例研究

目录&#xff1a; 4.4. 案例研究 4.4.2. 情况描述 4.4.3. 信息收集 4.4.3.2. 检查隐藏目录&#xff08;点目录&#xff09;的可能性 4.4.3.3. 使用 DB Browser for SQLite 打开 .db 文件 4.4.3.4. 寻找加密算法 4.4.3.5. 找到加密算法 4.4.3.6. 理解加密流程 4.4.3.7. 找到“Ke…

有关Java中的集合(2):Map<T>(底层源码分析)

学习目标 核心掌握Map集合 1.Map<K,V> ● 实现了Map接口的集合对象的集合元素&#xff1a; 成对的值 key-value 键值对 ● key对象是不能重复的. value可以重复。 ● 核心: 根据key获得value。 1.1 层级 public interface Map<K, V> {}1.2 常用方法 1.3 使用方法…

windows电脑上安装llama-factory实现大模型微调

一、安装环境准备 这是官方给的llama-factory安装教程&#xff0c;安装 - LLaMA Factory&#xff0c;上面介绍了linux系统上以及windows系统上如何正确安装。大家依照安装步骤基本能够完成安装&#xff0c;但是可能由于缺少经验或者相关的知识导致启动webUi界面运行相应内容时…

商米科技前端工程师(base上海)内推

1.根据原型或高保真设计&#xff0c;开发web、H5、小程序等类型的前端应用&#xff1b; 2.在指导下&#xff0c;高质量完成功能模块的开发&#xff0c;并负责各功能模块接口设计工作&#xff1b; 3.负责产品及相关支撑系统的开发及维护工作&#xff0c;不断的优化升级&#x…

HTTP四次挥手是什么?

四次挥手&#xff0c;这是TCP协议用来关闭连接的过程。四次挥手是确保两个主机之间能够安全、可靠地关闭连接的重要机制。我会用简单易懂的方式来讲解&#xff0c;帮助你理解它的原理和过程。 1. 什么是四次挥手&#xff1f; 定义 四次挥手是TCP协议用来关闭连接的过程。它通…

【iOS】小蓝书学习(七)

小蓝书学习&#xff08;七&#xff09; 前言第47条&#xff1a;熟悉系统框架第48条&#xff1a;多用枚举块&#xff0c;少用for循环第50条&#xff1a;构建缓存使选用NSCache而非NSDictionary第51条&#xff1a;精简initialize与load的实现代码第52条&#xff1a;别忘了NSTimer…

SyntaxError: positional argument follows keyword argument

命令行里面日常练手爬虫不注意遇到的问题&#xff0c;报错说参数位置不正确 修改代码后&#xff0c;运行如下图&#xff1a; 结果&#xff1a; 希望各位也能顺利解决问题&#xff0c;祝你好运&#xff01;

drawDB:一款免费数据库设计工具

drawDB 是一款基于 Web 的免费数据库设计工具&#xff0c;通过拖拽、复制、粘贴等方式进行数据库建模设计&#xff0c;同时可以生成相应的 SQL 脚本。 功能特性 drawDB 目前可以支持 MySQL、MariaDB、PostgreSQL、SQL Server 以及 SQLite 数据库&#xff0c;核心功能包括&…

FPGA开发,使用Deepseek V3还是R1(9):FPGA的全流程(详细版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…

Hive-05之查询 分组、排序、case when、 什么情况下Hive可以避免进行MapReduce

一、目标 掌握hive中select查询语句中的基本语法掌握hive中select查询语句的分组掌握hive中select查询语句中的join掌握hive中select查询语句中的排序 二、要点 1. 基本查询 注意 SQL 语言大小写不敏感SQL 可以写在一行或者多行关键字不能被缩写也不能分行各子句一般要分行…

人工智能之数学基础:矩阵的范数

本文重点 在前面课程中,我们学习了向量的范数,在矩阵中也有范数,本文来学习一下。矩阵的范数对于分析线性映射函数的特性有重要的作用。 矩阵范数的本质 矩阵范数是一种映射,它将一个矩阵映射到一个非负实数。 矩阵的范数 前面我们学习了向量的范数,只有当满足几个条…

I2C驱动(十一) -- gpio模拟的i2c总线驱动i2c-gpio.c分析

相关文章 I2C驱动(一) – I2C协议 I2C驱动(二) – SMBus协议 I2C驱动(三) – 驱动中的几个重要结构 I2C驱动(四) – I2C-Tools介绍 I2C驱动(五) – 通用驱动i2c-dev.c分析 I2C驱动(六) – I2C驱动程序模型 I2C驱动(七) – 编写I2C设备驱动之i2c_driver I2C驱动(八) – 编写I2C…

(KTransformers) RTX4090单卡运行 DeepSeek-R1 671B

安装环境为&#xff1a;ubuntu 22.04 x86_64 下载模型 编辑文件vim url.list 写入如下内容 https://modelscope.cn/models/unsloth/DeepSeek-R1-GGUF/resolve/master/DeepSeek-R1-Q4_K_M/DeepSeek-R1-Q4_K_M-00001-of-00009.gguf https://modelscope.cn/models/unsloth/Dee…