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

react 初体验

https://zh-hans.react.dev/ 官方中文文档

https://segmentfault.com/a/1190000012921279 学习

1.react安装

利用工具来构建脚手架

npm create vite@latest react项目名称 -- --template react创建的时候比较慢 耐心等

创建完成后

npm install
npm run dev    看好node版本  推荐21

2.添加 env

VITE_TITLE='项目开发环境'
VITE_APP_ENV = 'devlopment'
  "scripts": {"dev": "vite --mode dev -d proxy","test": "vite --mode test -d proxy","prod": "vite --mode prod -d proxy","build:test": "vite build --mode test","build:prod": "vite build --mode prod","lint": "eslint .","preview": "vite preview"},
const env = import.meta.env;<div className='title'>{env.VITE_TITLE}</div>

3.配置路由

https://blog.csdn.net/debbyDeng/article/details/84555817

npm install  react-router-dom
import { createBrowserRouter } from 'react-router-dom'
import React from 'react'
import MainLayout from '../layouts/MainLayout.jsx' //用来存放公共模块// React.lazy 表示懒加载页面组件
const Login = React.lazy(() => import('../pages/login/login.jsx'))
const Home = React.lazy(() => import('../pages/home/index.jsx'))
const router = createBrowserRouter([{path: '/login',Component: Login},{path: '/',Component: MainLayout,children: [{ index: true, Component: Home }]}
])
export default router

4.本地储存

npm install redux-persist

本地储存持久化

import { configureStore } from '@reduxjs/toolkit';
import countReducer from './modules/countStore';// 👇 redux-persist 相关导入
import { persistStore, persistReducer } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import storage from 'redux-persist/lib/storage'; // 使用 localStorage
// import { sessionStorage } from 'redux-persist/lib/storage' // 也可以使用 sessionStorage
// import AsyncStorage from '@react-native-async-storage/async-storage' // 移动端用 AsyncStorage// 👇 配置持久化选项
const persistConfig = {key: 'root',           // 存储的 keystorage,               // 存储引擎(localStorage)whitelist: ['count'],   // 只持久化的 reducer 名称(可选)  优先级高于 blacklist// blacklist: []       // 不想持久化的 reducer 名称 version: 1, // 版本号,当 reducer 数据结构变化时(比如新增了一个key 把object放到了这个key下面),需要更新版本号debug: process.env.NODE_ENV === 'development', // 开启调试模式,会在控制台打印哪些数据被保存/被恢复/有错误throttle: 2000, // 2秒保存一次  (默认是1000ms)migrate: (state, version) => { // 版本迁移函数 有点小复杂 后面再深究// 根据旧 state 和版本号,返回新 statereturn state;},stateReconciler: autoMergeLevel2, // 配置 state 合并策略 // 比如现在存了obj: { user: { name: '苗' }, count: 5 } 现在name是两层 如果现在user要变成obj: { user: { name: '苗', age: 24, }, count: 5, email: '123123' } // 那么autoMergeLevel2会自动合并成obj: { user: { name: '苗', age: 24, }, count: 5, email: '123123' }keyPrefix: 'myapp_', // 自定义前缀,避免与其他应用冲突 存储时变成:keyPrefix的值 + persist: + key的值
};// 👇 包装 reducer
const persistedReducer = persistReducer(persistConfig, countReducer);// 👇 创建 store
export const store = configureStore({reducer: {count: persistedReducer},middleware: (getDefaultMiddleware) =>getDefaultMiddleware({serializableCheck: false, // redux-persist 会报错,需关闭}),
});// 👇 创建 persistor
export const persistor = persistStore(store);// 💡 原来的 store 还是 export default
export default store;

单个 store 持久化

// store/modules/countStore.ts
import { createSlice } from '@reduxjs/toolkit';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';// 1. 配置持久化
const persistConfig = {key: 'count',        // localStorage 中的 key 是:myapp_persist:countstorage,             // 使用 localStorageversion: 1,keyPrefix: 'myapp_',  // 前缀
};// 2. 创建 slice
const countStore = createSlice({name: 'count',initialState: {count: 0},reducers: {increment(state) {state.count++;},decrement(state) {state.count--;},changeCount(state, action) {state.count = action.payload;},}
});// 3. 包装成持久化 reducer  关键一步!
const persistedReducer = persistReducer(persistConfig, countStore.reducer);// 4. 导出 actions 和 持久化后的 reducer
export const selectCount = (state) => state.count.count;
export const { increment, decrement, changeCount } = countStore.actions;//  最关键的一行:导出持久化后的 reducer
export default persistedReducer;
// store/modules/countStore.ts
import { createSlice } from '@reduxjs/toolkit';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';// 1. 配置持久化
const persistConfig = {key: 'trigger',        // localStorage 中的 key 是:myapp_persist:countstorage,             // 使用 localStorageversion: 1,keyPrefix: 'myapp_',  // 前缀
};// 2. 创建 slice
const triggerStore = createSlice({name: 'trigger',initialState: {trigger: 'sun',//触发主题 日月menuShow: true,//侧边栏},reducers: {changeTrigger(state, action) {state.trigger = action.payload;},changeMenuShow(state, action) {state.menuShow = action.payload;},},extraReducers: (builder) => {builder.addCase('persist/REHYDRATE', (state, action) => {// 1. 恢复 Redux 状态if (action.payload?.trigger) {state.trigger = action.payload.trigger;} else {// 如果没有持久化数据,用系统偏好const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;state.trigger = prefersDark ? 'moon' : 'sun';}// 2.  立刻同步 DOM,避免闪烁if (state.trigger === 'moon') {document.documentElement.classList.add('dark');} else {document.documentElement.classList.remove('dark');}// 3. 添加初始化标记(可选)document.documentElement.classList.add('theme-initialized');});}
});// 3. 包装成持久化 reducer 关键一步!
const persistedReducer = persistReducer(persistConfig, triggerStore.reducer);// 4. 导出 actions 和 持久化后的 reducer
export const selectTrigger = (state) => state.trigger.trigger;
export const selectMenuShow = (state) => state.trigger.menuShow;export const { changeTrigger, changeMenuShow } = triggerStore.actions;// ✅ 最关键的一行:导出持久化后的 reducer
export default persistedReducer;

✅ 总结:persistConfig 配置一览

配置项

是否必填

作用

建议值

key

✅ 必填

存储的 key 名

'root'

storage

✅ 必填

存储引擎

import storage from '...'

whitelist

❌ 可选

只存这些 reducer

['count']

blacklist

❌ 可选

不存这些 reducer

['loading']

version

❌ 可选

版本号

1

debug

❌ 可选

是否打印日志

开发时 true

throttle

❌ 可选

防抖时间

2000

migrate

❌ 可选

数据迁移

复杂时使用

stateReconciler

❌ 可选

合并策略

autoMergeLevel2

keyPrefix

❌ 可选

key 前缀

可选

http://www.dtcms.com/a/422988.html

相关文章:

  • 南华 NHXJ-02 汽车悬架检验台:技术特性与实操应用指南
  • 鄂湘赣新能源汽车产业质量技术创新联合体成立大会暨汽车网络安全标准专题培训会在汉圆满召开
  • 物联网智能安防系统
  • 洗头竖鞋带名片改良授权做网站不贵高端产品网站建设
  • 软考 系统架构设计师系列知识点之杂项集萃(160)
  • 汕头网站建设推广电子商务网站流程图
  • Axure教程:用中继器制作高亮搜索效果
  • WSL2 子系统启用 SSH 并使用 MobaXterm 连接
  • Oracle EBS ERP之报表开发—嵌入Web中的报表预览、报表打印
  • 网站上传可以通过wordpress作者 页面
  • 【信号处理基础】傅立叶级数、傅立叶变换、拉普拉斯变换与z变换
  • powershell脚本文件输出中文乱码解决办法
  • 二叉树的后序遍历【非递归版】
  • 一款专门为 WPF 打造的开源 Office 风格用户界面控件库
  • 【Java并发】揭秘Lock体系 -- 深入理解ReentrantLock
  • 数据可视化图表之——气泡图
  • 网站的搭建流程黑科技软件网站
  • 【征文计划】从掌心到像素:深度解析Rokid UXR 2.0的手势识别与自定义交互实战
  • 零知IDE——STM32F407VET6与GP2Y1014AU的粉尘监测系统实现
  • 网站建设怎么创业网站正建设中
  • 网站建站哪个好宁波建设局网站首页
  • Day31_【 NLP _1.文本预处理 _(3)文本数据分析】
  • 金融/财务图表的强大可视化引擎——Highcharts Stock
  • 如何将照片从Mac传输到安卓设备
  • 第四部分:VTK常用类详解(第112章 vtkGlyph2D 2D符号化类)
  • 如何将三星手机的照片传输到Mac——6种可行的方法
  • 《系统与软件工程功能规模测量IFPUG方法》(GB/T42449-2023)标准解读
  • ChatExcel将发布数据分析Mini AI 工作站
  • 通过AWS IAM Policy Simulator进行权限验证和模拟测试
  • AWS Glue ETL 自动化数据清洗:从概念到企业级实战