React 高级教程
使用 React 高级组件(HOC)实现的完整项目示例,包含权限控制、数据加载状态处理、性能优化等常见高级功能。创建一个简单的博客系统:
// 项目结构:
src/
|-- components/
| |-- ArticleList.jsx
| |-- Article.jsx
| |-- Header.jsx
| |-- LoginForm.jsx
| |-- UserProfile.jsx
| |-- WithLoading.jsx
| |-- AuthContext.jsx
| |-- WithAuth.jsx
|-- hocs/
| |-- withAuth.js
|-- hooks/
| |-- useFetch.js
| |-- useDebouncedFetch.js
|-- contexts/
| |-- UserContext.js
|-- pages/
| |-- HomePage.jsx
| |-- AdminPage.jsx
| |-- LoginPage.jsx
| |-- UserProfilePage.jsx
| |-- ArticleDetailPage.jsx
|-- App.jsx
|-- index.js// 首先安装必要依赖:react-router-dom
关键技术点:
1. 创建认证上下文 (AuthContext.jsx)
import { createContext, useContext, useState } from 'react';const AuthContext = createContext();export function AuthProvider({ children }) {const [user, setUser] = useState(null);const login = (userData) => {setUser({ ...userData, role: 'admin' }); // 模拟登录};const logout = () => {setUser(null);};return (<AuthContext.Provider value={{ user, login, logout }}>{children}</AuthContext.Provider>);
}export const useAuth = () => useContext(AuthContext);
2. 创建高阶组件 (WithAuth.jsx)
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';export const withAuth = (WrappedComponent, requiredRole = 'user') => {return (props) => {const { user } = useAuth();const navigate = useNavigate();if (!user) {navigate('/login');return null;}if (requiredRole === 'admin' && user.role !== 'admin') {return <div>无权限访问此页面</div>;}return <WrappedComponent {...props} user={user} />;};
};
3. 加载状态高阶组件 (WithLoading.jsx)
import { useState, useEffect } from 'react';export const withLoading = (WrappedComponent, fetchData) => {return (props) => {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {const loadData = async () => {try {const result = await fetchData();setData(result);} catch (err) {setError(err.message);} finally {setLoading(false);}};loadData();}, []);if (loading) return <div>Loading...</div>;if (error) return <div>Error: {error}</div>;return <WrappedComponent {...props} data={data} />;};
};
4. 自定义 Hook (useFetch.js)
import { useState, useEffect } from 'react';export const useFetch = (url) => {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {const fetchData = async () => {try {const response = await fetch(url);const result = await response.json();setData(result);} catch (err) {setError(err.message);} finally {setLoading(false);}};fetchData();}, [url]);return { data, loading, error };
};
5. 优化列表组件 (OptimizedList.jsx)
import React from 'react';const OptimizedList = React.memo(({ items, renderItem }) => {console.log('List re-rendered');return (<div style={{ maxHeight: '500px', overflow: 'auto' }}>{items.map((item, index) => (<div key={item.id || index}>{renderItem(item)}</div>))}</div>);
});export default OptimizedList;
6. 页面组件示例 (Admin.jsx)
import { withAuth } from '../components/WithAuth';
import { useFetch } from '../hooks/useFetch';
import OptimizedList from '../components/OptimizedList';const AdminPanel = ({ user }) => {const { data: posts, loading, error } = useFetch('/api/posts');if (loading) return <div>Loading posts...</div>;if (error) return <div>Error: {error}</div>;return (<div><h1>欢迎管理员 {user.name}</h1><h2>文章管理</h2><OptimizedListitems={posts}renderItem={(post) => (<div style={{ padding: '10px', borderBottom: '1px solid #ccc' }}><h3>{post.title}</h3><p>{post.content}</p></div>)}/></div>);
};// 使用高阶组件包裹,要求管理员权限
export default withAuth(AdminPanel, 'admin');
7. 主应用组件 (App.jsx)
// App.jsx
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { UserProvider } from './contexts/UserContext';
import HomePage from './pages/HomePage';
import AdminPage from './pages/AdminPage';
import LoginPage from './pages/LoginPage';
import UserProfilePage from './pages/UserProfilePage';
import ArticleDetailPage from './pages/ArticleDetailPage';const App = () => {return (<UserProvider><Router><Switch><Route path="/" exact component={HomePage} /><Route path="/login" component={LoginPage} /><Route path="/profile" component={UserProfilePage} /><Route path="/admin" component={AdminPage} /><Route path="/articles/:id" component={ArticleDetailPage} /></Switch></Router></UserProvider>);
};export default App;
8. 登录页面示例 (Login.jsx)
import React, { useState, useContext } from 'react';
import { UserContext } from '../contexts/UserContext';const LoginPage = () => {const { login } = useContext(UserContext);const [username, setUsername] = useState('');const [password, setPassword] = useState('');const handleSubmit = (e) => {e.preventDefault();// 假设我们直接使用固定的用户名和密码登录if (username === 'admin' && password === 'admin123') {login({ username, role: 'admin' });} else {alert('Invalid credentials');}};return (<form onSubmit={handleSubmit}><input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" /><input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" /><button type="submit">Login</button></form>);
};export default LoginPage;
9. 文章详细页 (ArticleDetailPage.jsx)
展示文章的详细信息,点击文章标题进入。
// pages/ArticleDetailPage.jsx
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useFetch } from '../hooks/useFetch';const ArticleDetailPage = () => {const { id } = useParams();const { data: article, loading, error } = useFetch(`/api/articles/${id}`);if (loading) return <p>Loading...</p>;if (error) return <p>Error: {error.message}</p>;return (<div><h1>{article.title}</h1><p>{article.content}</p></div>);
};export default ArticleDetailPage;
10. 用户个人资料页 (UserProfilePage.jsx)
用户可以更新个人资料。
// pages/UserProfilePage.jsx
import React, { useState, useContext } from 'react';
import { UserContext } from '../contexts/UserContext';const UserProfilePage = () => {const { user, logout } = useContext(UserContext);const [username, setUsername] = useState(user.username);const handleSave = () => {// 在这里可以将更新后的用户名保存到后端console.log('Username updated:', username);};return (<div><h1>User Profile</h1><input type="text" value={username} onChange={(e) => setUsername(e.target.value)} /><button onClick={handleSave}>Save</button><button onClick={logout}>Logout</button></div>);
};export default UserProfilePage;
11. 分页功能 (HomePage.jsx)
文章列表实现分页功能,每页显示一定数量的文章。
// pages/HomePage.jsx
import React, { useState } from 'react';
import { useFetch } from '../hooks/useFetch';
import { ArticleList } from '../components/ArticleList';const HomePage = () => {const [page, setPage] = useState(1);const { data: articles, loading, error } = useFetch(`/api/articles?page=${page}`);if (loading) return <p>Loading...</p>;if (error) return <p>Error: {error.message}</p>;return (<div><ArticleList articles={articles} /><button onClick={() => setPage(page - 1)} disabled={page === 1}>Previous</button><button onClick={() => setPage(page + 1)}>Next</button></div>);
};export default HomePage;
11. 防抖(useDebouncedFetch.js)
用于处理防抖操作,避免频繁请求。
// hooks/useDebouncedFetch.js
import { useState, useEffect } from 'react';export const useDebouncedFetch = (url, delay) => {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {const timer = setTimeout(() => {const fetchData = async () => {try {const response = await fetch(url);const result = await response.json();setData(result);} catch (error) {setError(error);} finally {setLoading(false);}};fetchData();}, delay);return () => clearTimeout(timer);}, [url, delay]);return { data, loading, error };
};
相关文章:
React 高级教程
使用 React 高级组件(HOC)实现的完整项目示例,包含权限控制、数据加载状态处理、性能优化等常见高级功能。创建一个简单的博客系统: // 项目结构: src/ |-- components/ | |-- ArticleList.jsx | |-- Article.jsx | |-- He…...
基于Qt 和微信小程序的用户管理系统:WebSocket + SQLite 实现注册与登录
目录 一. 概要 二. 技术栈 三. 系统功能设计 3.1 功能模块 3.2 数据表设计 四. 具体实现 4.1 Qt 服务端 4.1.1 初始化 WebSocket 服务器 4.1.2 用户管理界面 4.2 微信小程序端 4.2.1 注册功能 4.2.2 登录功能 五. 运行效果 六. 源码下载 一. 概要 在物联网和智能设备…...
在CT107D单片机综合训练平台上实现外部中断控制LED闪烁
引言 在单片机开发中,外部中断是一个非常重要的功能,它可以让单片机在检测到外部信号变化时立即做出响应。本文将详细介绍如何在CT107D单片机综合训练平台上使用外部中断来控制LED灯的闪烁。我们将使用两种不同的方式来实现这一功能:一种是在…...
HTML之JavaScript使用JSON
HTML之JavaScript使用JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON是JavaScript对象的字符串表示法,它使用文本表示一个js对象的信息,可以将json字符串转换…...
算法很美笔记(Java)——树
性质 树 上面的性质因为两个结点由一条边连成 结点数目越多,算法复杂度越高 二叉树 结构 层次遍历 利用队列,弹一个,加N个(队列里弹出一个元素,就把这个元素的所有孩子加进去) 具体来说:指…...
SQL面试题4:相互关注问题
引言 在社交媒体和各类社区平台蓬勃发展的当下,用户之间的关系网络成为了平台运营和数据分析的关键部分。相互关注作为一种重要的社交关系,不仅反映了用户之间的紧密程度,还对平台的社交生态、内容传播等方面有着深远影响。本文将聚焦于 SQL…...
ArcGIS基础知识之ArcMap基础设置——ArcMap选项:常规选项卡设置及作用
作为一名 GIS 从业者,ArcMap 是我们日常工作中不可或缺的工具。对于初学者来说,掌握 ArcMap 的基础设置是迈向 GIS 分析与制图的第一步。今天,就让我们一起深入了解 ArcMap 选项中常规选项卡的各个设置,帮助大家更好地使用这款强大的软件。 在 ArcMap 中,常规选项卡是用户…...
jvm 线程监控调试
文章目录 前言一、使用JDK工具转储线程文件(如jstack)1. 找到Java进程的PID:2. 使用jstack生成线程转储文件:3.验证生成的线程转储文件:二、分析文件1.使用在线工具进行分析上传thread-dump文件,等待解析完成2.查看分析结果总结前言 提示:使用jdk自带工具转储线程监控文…...
25、深度学习-自学之路-卷积神经网络基于MNIST数据集的程序展示
import keras #添加Keraskuimport sys,numpy as np from keras.utils import np_utilsimport osfrom keras.datasets import mnist print("licheng:""20"\n) np.random.seed(1)(x_train,y_train),(x_test,y_test) mnist.load_data() #第一次…...
【C++】解锁<list>的正确姿势
> 🍃 本系列为初阶C的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:[小编的个人主页])小编的个人主页 > 🎀 🎉欢迎大家点赞👍收藏⭐文章 > ✌️ 🤞 …...
Qt中的事件
写一个 可以拖动的按钮 DraggablePushButton.h 头文件 #ifndef DRAGGABLEPUSHBUTTON_H #define DRAGGABLEPUSHBUTTON_H#include <QPushButton> #include <QMouseEvent>class DraggablePushButton : public QPushButton {Q_OBJECTpublic:explicit DraggablePushBu…...
变化检测相关论文可读list
一些用得上的: 遥感变化检测常见数据集https://github.com/rsdler/Remote-Sensing-Change-Detection-Dataset/ 代码解读:代码解读 | 极简代码遥感语义分割,结合GDAL从零实现,以U-Net和建筑物提取为例 NeurIPS2024: https://mp.w…...
Ansible中playbook的变量
变量 playbook的变量有以下几种 在playbook中用户自定义的变量远程主机中由Ansible收集的变量在文件模板中使用的上述两种变量把任务结果作为一个变量使用,叫注册变量用户在执行playbook时,通过命令行传入的变量,叫做额外变量 在playbook中…...
亚信安全正式接入DeepSeek
亚信安全致力于“数据驱动、AI原生”战略,早在2024年5月,推出了“信立方”安全大模型、安全MaaS平台和一系列安全智能体,为网络安全运营、网络安全检测提供AI技术能力。自2024年12月DeepSeek-V3发布以来,亚信安全人工智能实验室利…...
相似性图相关性重构网络用于无监督跨模态哈希
《Similarity Graph-correlation Reconstruction Network for unsupervised cross-modal hashing》 摘要1. 引言2. 相关工作2.1. 监督跨模态哈希方法2.2. 无监督跨模态哈希方法 3. 方法论3.1 问题定义3.2 特征提取3.3 模态内关系图构建3.4. 局部关系图重置3.5. 跨模态关系图构建…...
【Bug】属性 PackageVersion 应在所有目标框架中具有单个值,但却具有以下值
文章目录 问题问题代码原因解决处理Bug的具体步骤 问题 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) NU1105 无法读取“x”的项目信息: 属性 PackageVersion 应在所有目标框架中具有单个值,但却具有以下值: 1.0.0, 1.0.5 x (net8.0-android), x (net8.…...
C++ Primer 类型转换
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
【CS61A 2024秋】Python入门课,全过程记录P7(Week13 Macros至完结)【完结撒花!】
文章目录 关于新的问题更好的解决方案Week13Mon Macros阅读材料Lab 11: Programs as Data, MacrosQ1: WWSD: QuasiquoteQ2: If ProgramQ3: Exponential PowersQ4: Repeat Wed SQL阅读材料Disc 11: MacrosQ1: Mystery MacroQ2: Multiple AssignmentQ3: Switch Optional Contest:…...
SSH隧道+Nginx:绿色通道详解(SSH Tunnel+nginx: Green Channel Detailed Explanation)
SSH隧道Nginx:内网资源访问的绿色通道 问题背景 模拟生产环境,使用两层Nginx做反向代理,请求公网IP来访问内网服务器的网站。通过ssh隧道反向代理来实现,重点分析一下nginx反代的基础配置。 实验环境 1、启动内网服务器的tomca…...
LabVIEW用户界面设计原则
在LabVIEW开发中,用户界面(UI)设计不仅仅是为了美观,它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性,尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
