1.类组件和函数组件
(1)类组件
javascript
import React, { Component } from 'react';
class UserProfile extends Component {
constructor(props) {
super(props);
this.state = {
userData: null,
isLoading: true,
};
this.timerId = null;
}
componentDidMount() {
// 模拟 API 调用
this.timerId = setTimeout(() => {
this.setState({
userData: { name: 'John Doe', age: 28 },
isLoading: false
});
}, 2000);
}
componentWillUnmount() {
// 清理工作:清除定时器
clearTimeout(this.timerId);
}
render() {
const { isLoading, userData } = this.state;
if (isLoading) {
return <div>Loading user profile...</div>;
}
return (
<div>
<h2>Welcome, {userData.name}!</h2>
<p>Age: {userData.age}</p>
<p>From: {this.props.city}</p> {/* 使用从父组件传来的 props */}
</div>
);
}
}
export default UserProfile;
(2)函数组件
javascript
import React, { useState, useEffect } from 'react';
const UserProfile = ({ city }) => {
// 使用 useState 替代 this.state
const [userData, setUserData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
// useEffect 替代生命周期方法
useEffect(() => {
// componentDidMount 的逻辑(以及 componentDidUpdate 的相关逻辑)
const timerId = setTimeout(() => {
setUserData({ name: 'John Doe', age: 28 });
setIsLoading(false);
}, 2000);
// cleanup 函数:替代 componentWillUnmount
return () => {
clearTimeout(timerId);
};
}, []); // 空依赖数组表示只在组件挂载时执行
if (isLoading) {
return <div>Loading user profile...</div>;
}
return (
<div>
<h2>Welcome, {userData.name}!</h2>
<p>Age: {userData.age}</p>
<p>From: {city}</p>
</div>
);
};
export default UserProfile;

2.高阶组件
高阶组件是一个函数,它接收一个组件作为参数,并返回一个新的增强型组件。
简单来说:高阶组件是用于组件复用的高级技巧,它本质上是一个包装器(wrapper)
javascript
const EnhancedComponent = higherOrderComponent(WrappedComponent);
为了解决 React 中的逻辑复用问题。在自定义 Hooks 出现之前,这是 React 中主要的逻辑复用方式。
应用:
- 权限控制: 利用高阶组件的 条件渲染特性可以对页面进行权限控制,权限控制一般分为两个维度:页面级别和 页面元素级别
- **组件渲染性能追踪:**借助父组件子组件生命周期规则捕获子组件的生命周期,可以方便的对某个组件的渲染时间进行记录
- 页面复用
3.哪些方法会触发 React 重新渲染?重新渲染 render 会做些什么?
- **setState()方法被调用:**但是这里有个点值得关注,执行 setState 的时候不一定会重新渲染。当 setState 传入 null 时,并不会触发 render。
- 父组件重新渲染:只要父组件重新渲染了,即使传入子组件的 props 未发生变化,那么子组件也会重新渲染,进而触发 render
重新渲染 render 会做些什么?
- 会对新旧 VNode 进行对比,也就是我们所说的Diff算法。
- 对新旧两棵树进行一个深度优先遍历,这样每一个节点都会一个标记,在到深度遍历的时候,每遍历到一和个节点,就把该节点和新的节点树进行对比,如果有差异就放到一个对象里面
- 遍历差异对象,根据差异的类型,根据对应对规则更新VNode
4.对React-Fiber的理解,它解决了什么问题?
Fiber 是 React 16 中全新的协调引擎(reconciliation engine),也是一种新的数据结构。
Fiber 是 React 的虚拟 DOM 的升级版,它让 React 能够实现增量渲染和更精细的任务控制。
旧架构的问题(Stack Reconciler)
在 React 16 之前,React 使用递归遍历虚拟 DOM 树来进行 diff 计算:
-
不可中断:一旦开始渲染,就必须完成整个树的计算
-
阻塞主线程:长时间的渲染会阻塞用户交互、动画等
-
性能瓶颈:复杂组件树会导致页面卡顿
Fiber 要解决的问题
-
可中断渲染:将渲染任务拆分成小任务,可以暂停和恢复
-
任务优先级:区分高优先级(用户交互)和低优先级(数据更新)任务
-
并发渲染:为未来的并发特性打下基础
5.常用的hook

1.useState
状态管理
2.usEffect

javascript
useEffect(() => {
// 设置操作
const timer = setInterval(() => {}, 1000);
const listener = () => {};
window.addEventListener('resize', listener);
// 清理函数(可选)
return () => {
clearInterval(timer); // 清除定时器
window.removeEventListener('resize', listener); // 移除监听
console.log('清理完成!'); // 其他清理工作
};
}, []);
useEffect
是:
-
🔧 副作用处理器:处理组件渲染之外的操作
-
⏰ 生命周期管理器:替代 componentDidMount、componentDidUpdate、componentWillUnmount
-
🧹 清理工具:提供清理函数避免内存泄漏
记住三个核心用法:
-
useEffect(fn)
- 每次渲染后执行 -
useEffect(fn, [])
- 只执行一次(挂载时) -
useEffect(fn, [a, b])
- a或b变化时执行
3.useContext
Context 的使用三步曲:
-
创建:
const MyContext = createContext();
-
提供:
<MyContext.Provider value={数据}>
-
使用:
useContext(MyContext)