前言
本文覆盖 React 所有核心基础知识点,每个模块包含:完整概念、所有语法细节、使用场景、边界情况、可直接运行的完整示例。尤其针对类组件完整生命周期、Hooks 依赖规则、State 异步更新、Ref 操作、Context 跨组件传值等高频难点做了完整拆解,适合系统学习与复习。
1. React 核心介绍与两种环境搭建
1.1 核心特性
- 声明式 UI:只描述 UI 最终形态,React 自动更新 DOM
- 组件化:页面拆分为独立、可复用、可组合的组件
- 虚拟 DOM:Diff 算法最小化 DOM 操作,提升性能
- 单向数据流:数据自上而下流动,便于追踪与调试
- 跨平台:React DOM(Web)、React Native(App)、React MiniProgram
1.2 搭建方式一:脚手架 create-react-app(开发推荐)
bash 运行
# 创建项目
npx create-react-app react-complete-guide
# 进入目录
cd react-complete-guide
# 启动
npm start
# 打包
npm run build
1.3 搭建方式二:CDN 引入(学习测试)
html 预览
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const App = <h1>React CDN 测试</h1>
ReactDOM.createRoot(document.getElementById('root')).render(App)
</script>
</body>
</html>
2. JSX 语法完整规则与使用细节
2.1 本质
JSX 是 React.createElement() 的语法糖,不是 HTML、不是模板引擎,最终编译为 JS 对象。
2.2 完整语法规则
- 必须有唯一根节点,可使用
<></>(React Fragment)不产生额外 DOM - 标签必须闭合:
<img />、<input />、<br /> - className 代替 class,htmlFor 代替 for
- 样式使用驼峰命名:fontSize、backgroundColor
- 注释使用
{/* 注释内容 */} - 可嵌入任意 JS 表达式:变量、函数、三元、运算
- 对象 / 数组可直接渲染,函数需调用
- JSX 自动防 XSS 注入,会转义危险字符
2.3 完整示例
jsx
function JsxDemo() {
const name = 'React'
const price = 200
const isVip = true
const style = { color: 'red', fontSize: '18px' }
const list = ['Java', 'Vue', 'React']
return (
<>
<h1 className="title" style={style}>Hello {name}</h1>
<p htmlFor="user">价格:{price > 100 ? '昂贵' : '平价'}</p>
<ul>
{list.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
{isVip && <p>尊享会员</p>}
{/* JSX 注释 */}
</>
)
}
3. React 元素创建与 React 18 根节点渲染
3.1 手动创建 React 元素
jsx
// 等价于 <h1 id="title">Hello</h1>
const element = React.createElement('h1', { id: 'title' }, 'Hello')
3.2 React 18 渲染方式
jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
)
StrictMode严格模式:检查过时 API、副作用、不安全生命周期
4. 组件定义:函数组件 / 类组件 / 纯组件
4.1 函数组件(现代 React 首选)
- 无 this、无生命周期、无 state(Hooks 可实现)
- 代码简洁、性能更好、易于测试
jsx
function FuncCom(props) {
return <div>函数组件:{props.name}</div>
}
4.2 类组件
- 继承
React.Component - 必须实现
render() - 拥有 state、生命周期、this
jsx
import { Component } from 'react'
class ClassCom extends Component {
render() {
return <div>类组件:{this.props.name}</div>
}
}
4.3 纯组件 PureComponent
- 自带浅比较
shouldComponentUpdate - 适合数据不变场景,避免无效渲染
jsx
import { PureComponent } from 'react'
class PureCom extends PureComponent {}
4.4 高阶组件 HOC(基础扩展)
jsx
const withLog = (Component) => {
return (props) => {
console.log('日志')
return <Component {...props} />
}
}
const App = withLog(() => <div>HOC</div>)
5. Props 完整用法
5.1 核心规则
- Props 是父→子单向传递
- Props 是只读的,不能修改
- 可传递:数据、函数、JSX、组件、children
5.2 基础传值
jsx
function Child({ name, age }) {
return <div>{name} - {age}</div>
}
function Parent() {
return <Child name="张三" age={20} />
}
5.3 默认 Props
jsx
Child.defaultProps = {
name: '匿名',
age: 0
}
5.4 Props 类型校验
bash 运行
npm i prop-types
jsx
import PropTypes from 'prop-types'
Child.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
list: PropTypes.array,
obj: PropTypes.object,
fn: PropTypes.func
}
5.5 children 插槽
jsx
function Card({ children }) {
return <div className="card">{children}</div>
}
function App() {
return (
<Card>
<h3>标题</h3>
<p>内容</p>
</Card>
)
}
5.6 解构赋值
jsx
function Child({ name, age }) { /*...*/ }
6. State 状态管理完整详解
6.1 核心概念
- State 是组件内部私有可变数据
- 修改 State → 触发组件重新渲染
- 类组件 setState 是异步批量更新
- 函数组件使用 useState
6.2 函数组件 useState
jsx
import { useState } from 'react'
function StateDemo() {
// 基础用法
const [count, setCount] = useState(0)
// 函数式更新(解决异步依赖旧值问题)
const add = () => setCount(prev => prev + 1)
return <button onClick={add}>{count}</button>
}
6.3 类组件 state
jsx
class ClassState extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
add = () => {
// 对象式
this.setState({ count: this.state.count + 1 })
// 函数式(推荐)
this.setState(prev => ({ count: prev.count + 1 }))
}
render() {
return <button onClick={this.add}>{this.state.count}</button>
}
}
6.4 setState 异步 & 批量更新
- React 会合并多次 setState 提升性能
- 如需同步获取最新值,可在
setState回调中获取(类组件)
jsx
this.setState({ count: 100 }, () => {
console.log(this.state.count) // 最新值
})
7. React 合成事件完整详解
7.1 特点
- React 实现合成事件,抹平浏览器差异
- 事件委托到 document,提升性能
- 事件名驼峰:onClick、onChange、onSubmit、onMouseEnter
7.2 this 指向问题
jsx
class EventCom extends Component {
constructor() {
super()
this.state = { num: 0 }
// 方式1:bind 绑定
this.handleClick = this.handleClick.bind(this)
}
handleClick() { this.setState({ num: this.state.num + 1 }) }
// 方式2:箭头函数(推荐)
handleChange = () => {}
render() {
return (
<>
<button onClick={this.handleClick}>bind</button>
{/* 方式3:行内箭头函数 */}
<button onClick={() => this.handleClick()}>行内</button>
</>
)
}
}
7.3 事件传参
jsx
const handleClick = (id, e) => {
console.log(id, e)
}
<button onClick={(e) => handleClick(100, e)}>传参</button>
7.4 阻止默认行为 & 冒泡
jsx
const handleLink = (e) => {
e.preventDefault() // 阻止跳转
e.stopPropagation() // 阻止冒泡
}
<a href="#" onClick={handleLink}>阻止</a>
8. 条件渲染全方案
8.1 方式 1:if/else(最灵活)
jsx
function IfDemo({ isLogin }) {
if (isLogin) return <h1>欢迎回来</h1>
return <h1>请登录</h1>
}
8.2 方式 2:三元运算符
jsx
<div>{isLogin ? '已登录' : '未登录'}</div>
8.3 方式 3:逻辑与 &&
jsx
{isLogin && <button>退出</button>}
8.4 方式 4:元素变量
jsx
let btn
if (isLogin) btn = <button>退出</button>
else btn = <button>登录</button>
return <div>{btn}</div>
8.5 阻止渲染:return null
jsx
function Hide() { return null }
9. 列表渲染与 Key 完整规范
9.1 基础渲染
jsx
const list = [
{ id: 1, name: 'Vue' },
{ id: 2, name: 'React' }
]
function List() {
return (
<ul>
{list.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)
}
9.2 Key 作用与规范
- Key 是虚拟 DOM Diff 的唯一标识,提升复用性能
- 必须唯一且稳定
- 禁止使用随机数、index 作为 key(会导致渲染错乱)
9.3 嵌套列表
jsx
{list.map(item => (
<div key={item.id}>
<p>{item.name}</p>
{item.children.map(child => (
<p key={child.id}>{child.name}</p>
))}
</div>
))}
10. Ref 引用与 DOM 操作
10.1 作用
- 获取真实 DOM 节点
- 获取子组件实例
- 保存可变值(不触发渲染)
10.2 函数组件 useRef
jsx
import { useRef } from 'react'
function RefDemo() {
const inputRef = useRef(null)
const focus = () => inputRef.current.focus()
return (
<>
<input ref={inputRef} />
<button onClick={focus}>聚焦</button>
</>
)
}
10.3 类组件 createRef
jsx
class RefClass extends Component {
inputRef = createRef()
focus = () => this.inputRef.current.focus()
render() {
return <input ref={this.inputRef} />
}
}
10.4 转发 Ref forwardRef
jsx
const Input = forwardRef((props, ref) => {
return <input ref={ref} />
})
function App() {
const ref = useRef()
return <Input ref={ref} />
}
11. 表单组件完整方案
11.1 受控组件(推荐)
状态驱动表单值,双向绑定
jsx
import { useState } from 'react'
function ControlForm() {
const [form, setForm] = useState({ user: '', pwd: '' })
const change = (e) => {
const { name, value } = e.target
setForm(prev => ({ ...prev, [name]: value }))
}
const submit = (e) => {
e.preventDefault()
console.log(form)
}
return (
<form onSubmit={submit}>
<input name="user" value={form.user} onChange={change} />
<input name="pwd" value={form.pwd} onChange={change} />
<button type="submit">提交</button>
</form>
)
}
11.2 非受控组件
jsx
function UnControlForm() {
const inputRef = useRef()
const getVal = () => console.log(inputRef.current.value)
return <input ref={inputRef} />
}
11.3 多选、单选、下拉框
jsx
<select value={form.city} onChange={change} name="city">
<option value="bj">北京</option>
</select>
12. 类组件完整生命周期(全钩子 + 场景)
12.1 三个阶段:挂载 → 更新 → 卸载
12.2 完整生命周期钩子 & 执行顺序 & 使用场景
1. 挂载阶段(首次渲染)
-
constructor()- 初始化 state、绑定 this
- 只执行一次
-
static getDerivedStateFromProps(props, state)- 由 props 派生 state
- 返回新 state 或 null
-
render()- 必须,返回 JSX
-
componentDidMount()- 真实 DOM 生成后执行
- 场景:网络请求、定时器、DOM 操作、订阅事件
2. 更新阶段(props/state/forceUpdate)
-
static getDerivedStateFromProps() -
shouldComponentUpdate(nextProps, nextState)- 返回布尔值,控制是否渲染
- 性能优化
-
render() -
getSnapshotBeforeUpdate(prevProps, prevState)- 更新前获取 DOM 信息
- 返回值传给 componentDidUpdate
-
componentDidUpdate(prevProps, prevState, snapshot)- 更新完成
- 场景:DOM 操作、新请求
3. 卸载阶段
-
componentWillUnmount()- 组件销毁前
- 场景:清除定时器、取消订阅、移除事件监听
4. 错误处理(捕获子组件错误)
static getDerivedStateFromError(error)componentDidCatch(error, info)
12.3 完整示例
jsx
class LifeFull extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
console.log('1. constructor')
}
static getDerivedStateFromProps(props, state) {
console.log('2. getDerivedStateFromProps')
return null
}
shouldComponentUpdate() {
console.log('3. shouldComponentUpdate')
return true
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('4. getSnapshotBeforeUpdate')
return 'snapshot'
}
componentDidMount() {
console.log('5. componentDidMount')
// 请求接口
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('6. componentDidUpdate', snapshot)
}
componentWillUnmount() {
console.log('7. componentWillUnmount')
// 清除定时器
}
render() {
console.log('render')
return <div onClick={() => this.setState({ c: 1 })}>生命周期</div>
}
}
13. React Hooks 常用完整详解
13.1 Hooks 规则
- 只在函数组件顶层调用
- 不要在循环 / 条件 / 嵌套函数中使用
- 只能在 React 函数组件或自定义 Hooks 中使用
13.2 useState
状态管理,支持函数式更新
jsx
const [count, setCount] = useState(0)
setCount(prev => prev + 1)
13.3 useEffect(副作用)
处理异步请求、定时器、DOM 操作
jsx
// 无依赖:每次更新执行
useEffect(() => {})
// 空依赖:仅挂载执行(DidMount)+ 卸载清除(WillUnmount)
useEffect(() => {
const timer = setInterval(()=>{},1000)
return () => clearInterval(timer)
}, [])
// 有依赖:依赖变化执行
useEffect(() => {}, [count])
13.4 useRef
获取 DOM、保存不渲染变量
jsx
const timerRef = useRef(null)
13.5 useMemo(缓存计算结果)
jsx
const total = useMemo(() => count * 2, [count])
13.6 useCallback(缓存函数)
jsx
const handle = useCallback(() => {}, [])
14. 组件组合、插槽与 Context 跨层级通信
14.1 Context 作用
跨多层级组件传值,避免 props 层层传递
14.2 完整示例
jsx
import { createContext, useContext, useState } from 'react'
// 1. 创建上下文
const Context = createContext()
// 2. 父组件提供
function ProviderCom({ children }) {
const [user, setUser] = useState('张三')
return (
<Context.Provider value={{ user, setUser }}>
{children}
</Context.Provider>
)
}
// 3. 子组件使用
function Child() {
const { user } = useContext(Context)
return <div>{user}</div>
}
// 4. 使用
function App() {
return (
<ProviderCom>
<Child />
</ProviderCom>
)
}
15. React 样式处理 5 种方案
15.1 行内样式
jsx
<div style={{ color: 'red' }}></div>
15.2 普通 CSS
jsx
import './index.css'
<div className="box"></div>
15.3 CSS Module(防冲突)
文件名:index.module.css
jsx
import style from './index.module.css'
<div className={style.box}></div>
15.4 样式组件 styled-components
bash 运行
npm i styled-components
jsx
import styled from 'styled-components'
const Div = styled.div`color:red;`
<Div></Div>
15.5 动态类名
jsx
<div className={active ? 'on' : 'off'}></div>
16. Fragment、Portal、错误边界
16.1 Fragment 空标签
jsx
<>内容</>
<Fragment key={id}></Fragment>
16.2 Portal 传送门
将组件渲染到指定 DOM 节点
jsx
import { createPortal } from 'react-dom'
createPortal(<div>弹窗</div>, document.body)
16.3 错误边界
捕获子组件崩溃,避免整个应用挂掉
jsx
class ErrorBoundary extends Component {
state = { hasError: false }
static getDerivedStateFromError() {
return { hasError: true }
}
render() {
if (this.state.hasError) return <div>出错了</div>
return this.props.children
}
}
17. 基础性能优化
- 使用
React.memo缓存函数组件 - 使用
useMemo缓存复杂计算 - 使用
useCallback缓存函数引用 - 合理设置 Key,避免索引 Key
- 懒加载组件
React.lazy+Suspense - 卸载前清除定时器 / 监听
- 避免不必要的 state 与渲染
总结
本文覆盖 React 所有基础核心知识点,从语法、组件、通信、生命周期、Hooks 到性能优化,全部包含完整定义、使用场景、边界规则、可直接运行代码。