React 是由 Meta(原 Facebook)开发并维护的声明式、组件化 前端库(常被称作框架),核心定位是「构建用户界面」,凭借「虚拟DOM、单向数据流、组件化」三大核心特性,成为当前最主流的前端开发方案之一。
React快速学习---中文文档
一、React 核心基础
1. 核心定位与设计理念
React 不是「全栈框架」,而是专注于 UI 层的库,核心设计理念:
- 声明式编程:只需描述「UI 应该是什么样」,而非「如何一步步构建 UI」(对比命令式编程),React 自动处理 DOM 更新;
- 组件化:将 UI 拆分为独立、可复用的「组件」,每个组件负责一部分界面,降低复杂度;
- 单向数据流:数据从父组件流向子组件,状态变更可追溯,避免数据混乱;
- 虚拟DOM(VDOM):内存中维护一份 DOM 抽象层,通过「diff 算法」对比新旧 VDOM,仅更新变化的部分,提升渲染性能。
2. 环境搭建(两种主流方式)
方式1:Create React App(CRA,官方脚手架,适合新手)
bash
# 安装(需Node.js 14+)
npx create-react-app my-react-app
# 启动项目
cd my-react-app
npm start
方式2:Vite(新一代构建工具,速度更快,推荐生产使用)
bash
# 创建Vite+React项目
npm create vite@latest my-react-app -- --template react
# 安装依赖并启动
cd my-react-app
npm install
npm run dev
3. JSX:React 的核心语法糖
JSX 是「JavaScript XML」的缩写,不是 HTML/JS,而是 React 提供的语法糖,最终会被 @babel/plugin-transform-react-jsx 编译为 React.createElement() 调用。
核心规则(必记)
- 根节点:JSX 必须有唯一根节点(或用
<React.Fragment>/<> </>空Fragment 避免多余 DOM); - 属性命名:采用「小驼峰」(如
className代替 HTML 的class,htmlFor代替for); - 表达式插入:用
{}包裹 JS 表达式(变量、三元运算、函数调用等,不能放语句如 if/for); - 注释写法:
{/* 这是JSX注释 */}; - 样式:行内样式需传对象(
style={``{ color: 'red', fontSize: '16px' }})。
示例代码
jsx
import React from 'react';
const UserCard = () => {
const name = '张三';
const isVip = true;
const getAge = () => 20;
return (
<div className="user-card">
{/* 表达式插入 */}
<h2>姓名:{name}</h2>
<p>年龄:{getAge()}</p>
{/* 条件渲染 */}
<p>会员状态:{isVip ? 'VIP用户' : '普通用户'}</p>
{/* 行内样式 */}
<button style={{ backgroundColor: 'blue', color: 'white' }}>
点击
</button>
</div>
);
};
export default UserCard;
4. 组件:React 的基本单元
React 组件分为「函数组件」(现代主流)和「类组件」(传统方式,逐渐淘汰),核心是「复用 UI 逻辑」。
(1)函数组件(推荐)
无状态组件 → 引入 Hooks 后支持状态,简洁、易维护:
jsx
// 无参数基础组件
const Hello = () => {
return <h1>Hello React</h1>;
};
// 带Props的组件
const Greeting = (props) => {
// 解构Props,简化写法
const { name, age } = props;
return <p>你好{name},年龄{age}</p>;
};
// 使用组件
const App = () => {
return (
<div>
<Hello />
<Greeting name="李四" age={22} />
</div>
);
};
(2)类组件(兼容旧代码)
需继承 React.Component,通过 this 访问 props/state:
jsx
import React, { Component } from 'react';
class Counter extends Component {
// 初始化状态
state = { count: 0 };
// 事件处理(需绑定this,或用箭头函数)
increment = () => {
// setState是异步的,更新状态必须用setState,不能直接修改this.state
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>计数:{this.state.count}</p>
<button onClick={this.increment}>+1</button>
</div>
);
}
}
5. Props:组件的「输入参数」
Props(Properties)是父组件向子组件传递数据的唯一方式,核心特性:
- 只读性:子组件不能修改 Props(单向数据流);
- 默认Props :通过
defaultProps或函数默认参数设置; - Props校验 :用
prop-types库校验参数类型,避免传参错误。
示例:Props 校验与默认值
jsx
import React from 'react';
import PropTypes from 'prop-types';
const Product = ({ name, price, stock = 0 }) => {
return (
<div>
<h3>{name}</h3>
<p>价格:{price}元</p>
<p>库存:{stock}件</p>
</div>
);
};
// Props 校验
Product.propTypes = {
name: PropTypes.string.isRequired, // 必传字符串
price: PropTypes.number.isRequired, // 必传数字
stock: PropTypes.number // 可选数字
};
// 默认Props(也可直接用函数默认参数)
Product.defaultProps = {
stock: 0
};
6. State:组件的「内部状态」
State 是组件自身可修改的数据,触发组件重新渲染,核心规则:
- 不可直接修改 :类组件需用
this.setState(),函数组件需用useState返回的更新函数; - 异步更新:setState/useState 更新函数是异步的,依赖当前状态更新时需传「函数形式」;
- 函数组件 State :通过
useStateHook 实现,支持多状态拆分。
示例:函数组件 State(主流写法)
jsx
import { useState } from 'react';
const Counter = () => {
// 声明状态:[状态值, 更新函数]
const [count, setCount] = useState(0);
const [message, setMessage] = useState('初始消息');
// 依赖当前状态的更新(传函数)
const increment = () => {
setCount(prevCount => prevCount + 1); // 推荐:用前一次状态计算
};
return (
<div>
<p>计数:{count}</p>
<button onClick={increment}>+1</button>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="输入消息"
/>
</div>
);
};
7. 生命周期(类组件)与副作用(函数组件)
(1)类组件生命周期(三大阶段)
| 阶段 | 核心钩子函数 | 作用 |
|---|---|---|
| 挂载阶段 | constructor → render → componentDidMount | 初始化状态 → 渲染DOM → DOM挂载完成(请求数据) |
| 更新阶段 | shouldComponentUpdate → render → componentDidUpdate | 判断是否更新 → 重新渲染 → 更新完成(更新DOM) |
| 卸载阶段 | componentWillUnmount | 组件卸载前(清理定时器、取消请求) |
(2)函数组件:useEffect 替代生命周期
useEffect 是处理「副作用」(数据请求、DOM操作、定时器等)的核心 Hook,语法:
jsx
import { useState, useEffect } from 'react';
const DataFetch = () => {
const [data, setData] = useState(null);
// 模拟componentDidMount(仅挂载时执行)
useEffect(() => {
// 副作用逻辑:请求数据
fetch('https://api.example.com/data')
.then(res => res.json())
.then(data => setData(data));
// 清理函数(模拟componentWillUnmount)
return () => {
// 取消请求、清理定时器等
console.log('组件卸载,清理副作用');
};
}, []); // 依赖数组为空:仅执行一次
// 依赖count的副作用(count变化时执行)
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `计数:${count}`;
}, [count]); // 依赖数组:仅count变化时执行
return <div>{data ? JSON.stringify(data) : '加载中...'}</div>;
};
8. 事件处理、条件渲染、列表渲染
(1)事件处理
React 事件是「合成事件」(跨浏览器兼容),命名为小驼峰(如 onClick),注意类组件 this 绑定问题:
jsx
// 函数组件事件(简单)
const Button = () => {
const handleClick = (e) => {
e.preventDefault(); // 阻止默认行为
console.log('按钮点击');
};
return <button onClick={handleClick}>点击我</button>;
};
(2)条件渲染
通过 JS 逻辑控制 UI 显示/隐藏,常用方式:
jsx
const Auth = ({ isLogin }) => {
// 方式1:if-else
if (isLogin) return <p>已登录</p>;
return <button>登录</button>;
// 方式2:三元表达式
// return isLogin ? <p>已登录</p> : <button>登录</button>;
// 方式3:&&运算符(仅满足条件时渲染)
// return isLogin && <p>已登录</p>;
};
(3)列表渲染
用 map 遍历数组,必须加 key(唯一标识,优先用ID,不用index):
jsx
const TodoList = () => {
const todos = [
{ id: 1, text: '学习React' },
{ id: 2, text: '写代码' },
{ id: 3, text: '总结知识点' }
];
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
};
9. 表单处理
分为「受控组件」(推荐)和「非受控组件」:
(1)受控组件(值由State控制)
jsx
import { useState } from 'react';
const Form = () => {
const [formData, setFormData] = useState({
username: '',
gender: 'male',
agree: false
});
// 统一处理表单变更
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData(prev => ({
...prev,
[name]: type === 'checkbox' ? checked : value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('表单数据:', formData);
};
return (
<form onSubmit={handleSubmit}>
{/* 输入框 */}
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
placeholder="用户名"
/>
{/* 单选框 */}
<label>
<input
type="radio"
name="gender"
value="male"
checked={formData.gender === 'male'}
onChange={handleChange}
/>
男
</label>
<label>
<input
type="radio"
name="gender"
value="female"
checked={formData.gender === 'female'}
onChange={handleChange}
/>
女
</label>
{/* 复选框 */}
<label>
<input
type="checkbox"
name="agree"
checked={formData.agree}
onChange={handleChange}
/>
同意协议
</label>
<button type="submit">提交</button>
</form>
);
};
(2)非受控组件(用Ref获取值)
适合简单场景(如文件上传):
jsx
import { useRef } from 'react';
const UncontrolledForm = () => {
const inputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
console.log('输入值:', inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">提交</button>
</form>
);
};
二、React 进阶特性
1. Hooks 全解析(React 16.8+ 核心)
Hooks 解决类组件「复用逻辑复杂、this 混乱、组件拆分难」的问题,核心 Hooks 及场景:
| Hook 名称 | 核心作用 | 适用场景 |
|---|---|---|
| useState | 声明组件状态 | 管理组件内部简单状态(如计数、输入值) |
| useEffect | 处理副作用 | 数据请求、DOM操作、定时器/清理 |
| useContext | 读取Context数据 | 跨组件传值(避免Props透传) |
| useRef | 保存可变值/访问DOM | 获取DOM元素、保存定时器ID |
| useReducer | 复杂状态管理(替代useState) | 状态逻辑复杂、多状态联动(如表单) |
| useCallback | 缓存函数(避免子组件重复渲染) | 传递给子组件的回调函数 |
| useMemo | 缓存计算结果(避免重复计算) | 复杂计算(如列表过滤、排序) |
| useLayoutEffect | 同步执行副作用(DOM更新后立即执行) | 需同步修改DOM样式(避免闪烁) |
| useImperativeHandle | 自定义暴露给父组件的Ref方法 | 父组件调用子组件方法(少用) |
示例:useReducer(复杂状态管理)
jsx
import { useReducer } from 'react';
// 1. 定义reducer函数(纯函数)
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
case 'RESET':
return { ...state, count: 0 };
default:
return state;
}
};
// 2. 使用useReducer
const Counter = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>计数:{state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+1</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>-1</button>
<button onClick={() => dispatch({ type: 'RESET' })}>重置</button>
</div>
);
};
2. Context API:跨组件传值
解决「Props 透传」(多层组件传值)问题,核心步骤:创建 Context → 提供 Provider → 消费数据。
jsx
import { createContext, useContext, useState } from 'react';
// 1. 创建Context(默认值可选)
const ThemeContext = createContext('light');
// 2. 提供Context(Provider)
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// 3. 消费Context(useContext)
const ThemedButton = () => {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button
onClick={toggleTheme}
style={{
backgroundColor: theme === 'light' ? 'white' : 'black',
color: theme === 'light' ? 'black' : 'white'
}}
>
当前主题:{theme},切换主题
</button>
);
};
// 4. 使用
const App = () => {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
);
};
3. Refs 与 Portals
(1)Refs 进阶:useRef vs createRef
useRef:函数组件专用,每次渲染返回同一个Ref对象;createRef:类组件/函数组件均可,每次渲染创建新对象。
(2)Portals:渲染到DOM任意位置
解决「父组件 overflow:hidden/ z-index 限制」问题(如弹窗、模态框):
jsx
import { createPortal } from 'react-dom';
const Modal = ({ children }) => {
// 找到public/index.html中的#modal-root
const modalRoot = document.getElementById('modal-root');
return createPortal(
<div style={{ position: 'fixed', top: 0, left: 0, zIndex: 9999 }}>
{children}
</div>,
modalRoot
);
};
// 使用
const App = () => {
return (
<div style={{ overflow: 'hidden', height: '200px' }}>
<Modal>
<h2>这是一个弹窗</h2>
</Modal>
</div>
);
};
4. Error Boundaries:错误捕获
防止子组件错误导致整个应用崩溃,仅能捕获类组件(函数组件需封装):
jsx
import React, { Component } from 'react';
class ErrorBoundary extends Component {
state = { hasError: false, error: null };
// 捕获错误
static getDerivedStateFromError(error) {
return { hasError: true };
}
// 记录错误日志
componentDidCatch(error, info) {
console.error('组件错误:', error, info);
this.setState({ error });
}
render() {
if (this.state.hasError) {
// 自定义错误UI
return <div>出错了:{this.state.error?.message}</div>;
}
return this.props.children;
}
}
// 使用
const BuggyComponent = () => {
// 故意抛出错误
throw new Error('组件内部错误!');
return <p>正常内容</p>;
};
const App = () => {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
};
5. 性能优化核心
(1)React.memo:缓存函数组件
浅比较Props,避免无意义重渲染:
jsx
// 包裹组件,仅Props变化时重渲染
const MemoizedComponent = React.memo(({ name }) => {
console.log('组件渲染了');
return <p>{name}</p>;
});
(2)useCallback/useMemo:缓存函数/计算结果
jsx
import { useCallback, useMemo, useState } from 'react';
const OptimizedComponent = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState('张三');
// 缓存函数:仅依赖name变化时重新创建
const handleClick = useCallback(() => {
console.log('姓名:', name);
}, [name]);
// 缓存计算结果:仅count变化时重新计算
const doubleCount = useMemo(() => {
console.log('计算doubleCount');
return count * 2;
}, [count]);
return (
<div>
<p>计数:{count},双倍:{doubleCount}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={handleClick}>打印姓名</button>
</div>
);
};
(3)懒加载:React.lazy + Suspense
减少首屏加载体积:
jsx
import { lazy, Suspense } from 'react';
// 懒加载组件
const LazyComponent = lazy(() => import('./LazyComponent'));
const App = () => {
return (
<div>
{/* Suspense:加载中占位 */}
<Suspense fallback={<div>加载中...</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
三、React 生态与工程化
1. React Router(路由管理,v6 主流)
核心功能:路由跳转、参数传递、嵌套路由、路由守卫。
jsx
import {
BrowserRouter as Router,
Routes,
Route,
Link,
useParams,
useNavigate
} from 'react-router-dom';
// 页面组件
const Home = () => <h2>首页</h2>;
const User = () => {
// 获取路由参数
const { id } = useParams();
// 编程式导航
const navigate = useNavigate();
return (
<div>
<h2>用户页:{id}</h2>
<button onClick={() => navigate('/')}>返回首页</button>
</div>
);
};
// 嵌套路由
const Dashboard = () => {
return (
<div>
<h2>控制台</h2>
<Link to="profile">个人信息</Link>
<Routes>
<Route path="profile" element={<p>个人信息内容</p>} />
</Routes>
</div>
);
};
// 路由配置
const App = () => {
return (
<Router>
<nav>
<Link to="/">首页</Link>
<Link to="/user/123">用户123</Link>
<Link to="/dashboard">控制台</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/user/:id" element={<User />} />
<Route path="/dashboard/*" element={<Dashboard />} />
</Routes>
</Router>
);
};
2. 状态管理生态
- 轻量场景:Context + useReducer(替代Redux);
- 中大型项目:Redux Toolkit(RTK,简化Redux);
- 服务端状态:React Query/SWR(处理异步数据,缓存、刷新、重试)。
Redux Toolkit 示例
jsx
// store/slice/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
increment: (state) => {
state.count += 1; // RTK允许直接修改(内部用Immer)
},
decrement: (state) => {
state.count -= 1;
}
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
// store/index.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slice/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer
}
});
// 组件中使用
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './store/slice/counterSlice';
const Counter = () => {
const count = useSelector(state => state.counter.count);
const dispatch = useDispatch();
return (
<div>
<p>计数:{count}</p>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
</div>
);
};
// 根组件包裹Provider
import { Provider } from 'react-redux';
import { store } from './store';
const App = () => {
return (
<Provider store={store}>
<Counter />
</Provider>
);
};
3. 工程化配套
- 打包构建:Vite/Webpack(处理ES6+、CSS、静态资源);
- 代码规范:ESLint(语法检查)+ Prettier(代码格式化);
- 测试:Jest(单元测试)+ React Testing Library(组件测试);
- SSR/SSG:Next.js(React 服务端渲染框架,解决SEO、首屏加载);
- 移动端:React Native(用React写原生App)。
四、React 最佳实践
- 组件设计:原子化拆分(基础组件→业务组件→页面组件),组合优于继承;
- 状态管理:局部状态用useState,跨组件用Context+useReducer,大型项目用RTK;
- 性能优化:避免不必要的渲染(React.memo/useCallback/useMemo),懒加载组件;
- 代码规范:组件命名PascalCase,文件按功能划分(如/components、/hooks、/store);
- 错误处理:用Error Boundary捕获错误,异步请求加loading/错误状态;
- Hooks 规则:仅在函数组件/自定义Hook中调用,仅在顶层调用(不能放if/for)。
总结
- 核心基础:React 以组件化为核心,JSX 是语法糖,Props 传值、State 管理内部状态,useEffect 处理副作用,覆盖了UI构建的基础能力;
- 进阶特性:Hooks 解决了类组件的痛点,Context 解决跨组件传值,Refs/Portals/Error Boundaries 完善特殊场景,性能优化(memo/useCallback/useMemo)提升应用体验;
- 生态工程化:React Router 管理路由,Redux Toolkit 处理状态,Vite/Next.js 提升工程化能力,遵循最佳实践可构建高可维护性的 React 应用。