React
React 简介
- 由 Meta 公司开发,用于构建 Web 和原生交互界面的库
- 优势:
- 组件化开发方式
- 高性能
- 丰富生态
- 跨平台支持
开发环境创建
使用 create-react-app 快速创建项目:
1 | npx create-react-app react-basic |
JSX 基础
基本概念
- JSX 是 JavaScript 和 HTML 的混合语法
- 示例:
1 | const message = 'this is message' |
表达式使用
使用大括号
{}嵌入 JavaScript 表达式支持变量、函数调用等
1
2
3
4
5
6
7
8
9
10
11function App() {
function formatDate() {
return new Date().toLocaleDateString()
}
return (
<div>
<p>当前日期: {formatDate()}</p>
</div>
)
}
列表渲染
使用 map 方法渲染列表:
1 | const list = [ |
条件渲染
使用
&&运算符1
2
3
4
5
6
7
8
9function App() {
const name = '张三'
return (
<div>
<p>用户名: {name}</p>
</div>
)
}使用三元表达式
?:1
2
3
4
5
6
7
8
9
10
11
12
13function App() {
const isLoading = true
return (
<div>
{isLoading ? (
<span>加载中...</span>
) : (
<span>内容加载完成</span>
)}
</div>
)
}复杂条件渲染
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function App() {
const status = 2 // 0|1|2
const renderContent = () => {
if (status === 0) {
return <div>状态0的内容</div>
} else if (status === 1) {
return <div>状态1的内容</div>
} else {
return <div>默认内容</div>
}
}
return (
<div>
{renderContent()}
</div>
)
}
JSX 表达式使用详解
基本语法
在 JSX 中,使用 {} 包裹 JavaScript 表达式:
1 | const name = '李四'; |
变量渲染
1 | function Greeting() { |
函数调用
1 | function formatName(user) { |
运算表达式
1 | function Calculator() { |
对象属性访问
1 | const product = { |
数组方法
1 | const numbers = [1, 2, 3, 4, 5]; |
Lodash 工具库
简介
Lodash 是一个流行的 JavaScript 实用工具库,提供了许多高效、可靠的函数,可以简化数组、对象、字符串等数据类型的操作。
安装
1 | npm install lodash |
常用方法示例
1. 数组操作
1 | import _ from 'lodash'; |
2. 对象操作
1 | // 深拷贝对象 |
3. 字符串处理
1 | // 转换字符串格式 |
4. 实用函数
1 | // 防抖函数 |
事件绑定
基本语法
1 | function App(){ |
事件参数
1 | const clickHandler = (e)=>{ |
自定义参数
1 | <button onClick={()=>clickHandler('jack')}>click me</button> |
组件基础
组件定义
1 | function Button(){ |
状态管理 useState
基本使用
1 | function App(){ |
状态修改规则
- 状态是只读的,必须通过 set 方法更新
- 对象类型状态需要提供全新对象
样式处理
行内样式
1 | <div style={{ color:'red' }}>text</div> |
这个实际上是react语法的大括号里面套了一个对象
CSS 类名
1 | import './index.css' |
表单控制
受控绑定
表单元素的值完全由React状态控制,每次输入都会触发状态更新,实现数据与UI的同步绑定。
1 | function App() { |
非受控绑定
通过ref直接操作DOM获取表单值,React不直接管理输入过程,适合简单场景或集成第三方库。
1 | function App() { |
组件通信
父子通信(父传子)
通过props将父组件数据传递给子组件。
1 | function Son(props) { |
父子通信(子传父)
父组件传递回调函数给子组件,子组件调用该函数传回数据。
1 | function Son({ onGetMsg }) { |
兄弟组件通信
通过状态提升,将共享状态放在共同的父组件中管理。
1 | function App() { |
跨层组件通信
使用Context API实现跨层级数据传递。
1 | const MsgContext = createContext(); |
副作用管理
什么是副作用
副作用是指组件渲染过程中与外部系统的交互操作,这些操作可能会影响其他组件或产生外部可观察的变化。
React组件的主要工作是渲染UI,但有时需要执行数据获取、订阅事件、手动修改DOM等”副作用”操作。
何时需要考虑副作用
在以下场景中需要使用useEffect处理副作用:
- 数据获取:组件加载后从API获取数据
- 事件订阅:添加/移除事件监听器
- DOM操作:手动修改DOM元素
- 定时器:设置/清除定时器
- 第三方库集成:初始化非React库
基础使用
1 | useEffect(() => { |
清除副作用
1 | useEffect(() => { |
依赖项详解
依赖项数组决定了副作用函数何时重新执行:
无依赖数组:
1
2
3useEffect(() => {
// 每次组件渲染后都会执行
});空依赖数组:
1
2
3useEffect(() => {
// 仅在组件挂载时执行一次
}, []);有依赖项:
1
2
3
4useEffect(() => {
// 在组件挂载时执行
// 当依赖项的值变化时重新执行
}, [count, name]); // 依赖 count 和 name 的变化
自定义Hook
封装可复用的逻辑,必须以use开头命名。
1 | //这里分装了一个只会true false变换的变量 |
Hooks使用规则
- 只能在函数组件或自定义Hook的顶层调用
- 不可在循环、条件判断或嵌套函数中调用Hook
1 | // 错误示例 |
Redux 状态管理
Redux 介绍
Redux 是 React 最常用的集中状态管理工具,类似于 Vue 中的 Pinia/Vuex,可以独立于框架运行。它的主要作用是通过集中管理的方式管理应用的状态。
Redux 核心概念
数据流架构
Redux 的数据修改遵循严格的单向数据流规则:
- State:一个对象,存放管理的数据
- Action:一个对象,描述如何修改数据
- Reducer:一个函数,根据 action 的描述更新 state
基本使用流程
- 定义 reducer 函数
- 使用 createStore 生成 store 实例
- 使用 store.subscribe 订阅数据变化
- 使用 store.dispatch 提交 action
- 使用 store.getState 获取最新状态
Redux 与 React 集成
环境配置
React官方要求安装Redux Toolkit和react-redux插件
前者是工具集合简化书写,后者用来链接react组件和redux
1 | npm install @reduxjs/toolkit react-redux |
Store 结构设计
index.js负责组合modules里的所有子模块,并导出store
1 | /store |
创建 Store
1 | import { configureStore } from '@reduxjs/toolkit' |
注入 React 应用
1 | import { Provider } from 'react-redux' |
Redux Toolkit 使用
创建 Slice
1 | import { createSlice } from '@reduxjs/toolkit' |
组件中使用
1 | import { useSelector, useDispatch } from 'react-redux' |
高级用法
异步 Action
1 | const fetchUserData = () => { |
1 | const dispatch = useDispatch() |
Action 传参
1 | reducers: { |
1 | // 组件中使用 |
调试工具
Redux DevTools 提供了强大的调试功能,可以实时查看 state 变化和 action 提交记录。
React Router
前端路由实现了不同URL路径显示不同组件的功能,所有的页面跳转都在浏览器端完成,无需向服务器请求完整页面。
环境搭建
1 | npm install react-router-dom |
路由模块化
将路由配置单独抽离为模块,保持项目结构清晰
推荐目录结构:
1 | /src |
路由导航
声明式导航
使用<Link>组件实现导航,类似HTML的<a>标签但不会刷新页面
1 | <Link to="/about">关于我们</Link> |
编程式导航
通过useNavigatehook在代码中控制跳转,适合表单提交后等场景
1 | const navigate = useNavigate(); |
路由传参
1. searchParams
参数会显示在URL中,适合传递筛选条件等简单参数
1 | // 传参代码 |
2. params
参数会成为URL路径的一部分,适合传递资源ID等必要参数
1 | // 路由配置中需要定义参数占位符 |
3. state
参数不会显示在URL中,适合传递敏感数据或复杂对象
1 | // 传参代码 |
嵌套路由
配置方法
通过children属性定义嵌套关系,Outlet作为子路由的渲染出口
1 | const router = createBrowserRouter([ |
高级配置
404路由
1 | { |
路由模式
1. History 模式 (createBrowserRouter)
特点与配置
1 | // 创建方式 |
优势:
- URL更简洁美观(无#号)
- 符合标准URL规范
- 支持HTML5 History API
注意事项:
服务器配置要求:
- 所有路径请求都应返回index.html
- 需要配置URL重写规则
常见服务器配置:
1
2
3
4
5
6# Nginx生产配置
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}适用场景:
- 生产环境
- 需要SEO友好的项目
- 需要干净URL的项目
Hash 模式 (createHashRouter)
特点与配置
1 | // 创建方式 |
优势:
- 无需服务器特殊配置
- 兼容性极佳(支持IE9+)
- 适合静态文件服务器
特点:
URL格式:
1
2http://example.com/#/path
http://example.com/#/user/123工作原理:
- 使用URL hash部分(#后的内容)实现路由
- 改变hash不会触发页面刷新
- 监听hashchange事件实现路由切换
适用场景:
- 静态网站托管(GitHub Pages等)
- 旧版浏览器支持
- 快速原型开发
- 无服务器配置权限的情况
生产境建议
首选History模式:
- 配置服务器支持URL重写
- 提供更专业的用户体验
Hash模式备用方案:
当无法控制服务器配置时使用
添加兼容性提示:
1
2
3
4// 检测浏览器兼容性
if (!window.history.pushState) {
alert('建议使用现代浏览器获得更好体验');
}
混合模式策略:
1
2
3
4
5
6
7// 根据环境自动选择路由模式
const isProduction = process.env.NODE_ENV === 'production';
const createRouter = isProduction ? createBrowserRouter : createHashRouter;
const router = createRouter([
// 路由配置
]);
React + TypeScript
项目初始化与配置
1 | # 使用 npm |
目录结构
1 | -src |
状态管理最佳实践
useState 类型安全用法
1 | // 基础类型 - 依赖类型推断 |
useRef 类型安全用法
1 | // DOM引用 |
配置路径别名
修改 vite.config.ts
1 | import { defineConfig } from 'vite' |
创建 tsconfig.json配置
1 | { |
安装 Ant Design
1 | npm install antd @ant-design/icons |
按需加载样式配置
修改 vite.config.ts:
1 | import { defineConfig } from 'vite' |
配置路由
安装 react-router-dom
1 | npm install react-router-dom @types/react-router-dom |
路由配置
1 | src/router/index.tsx |
修改 main.tsx
1 | import React from 'react' |
组件Props类型定义
基础组件Props
1 | interface ButtonProps { |
复杂组件Props
1 | interface DataTableProps<T> { |
事件处理类型安全
1 | // 表单事件 |
API请求类型安全
1 | interface ApiResponse<T> { |
Context API类型安全
1 | interface ThemeContextType { |
高阶组件类型处理
1 | interface WithLoadingProps { |
axios安装配置
安装axios
1 | npm i axios |
简易封装
1 | import axios from 'axios' |
可以在一个index.ts里面把所有工具类都给导出:
1 | import requestInstance from './http' |
封装泛型
1 | export type ResType<T> = { |
封装请求函数
1 | import { http } from '@/utils' |
测试API函数
1 | fetchChannelAPI().then((res) => { |
- 本文作者: NICK
- 本文链接: https://nicccce.github.io/TechNotes/React-Note/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!