Component API
React.Component 是类组件的基础 API,提供生命周期方法和状态管理。
概述
React.Component 是使用 ES6 class 定义 React 组件时的基类。 它提供了完整的生命周期方法、状态管理和上下文访问。
💡 提示: 如果你不需要类组件的完整功能, 推荐使用函数组件和 Hooks,它们更简洁且易于理解。
基本用法
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}类声明
要定义一个 React 组件类,需要继承 React.Component:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}生命周期方法
组件生命周期分为三个主要阶段:挂载、更新和卸载。
挂载 (Mounting)
这些方法在组件实例被创建和插入 DOM 时按顺序调用:
constructor()- 构造函数static getDerivedStateFromProps()- 从 props 派生状态render()- 渲染 UIcomponentDidMount()- 组件挂载后
更新 (Updating)
当组件的 props 或 state 发生变化时:
static getDerivedStateFromProps()- 从 props 派生状态shouldComponentUpdate()- 是否应该更新render()- 渲染 UIgetSnapshotBeforeUpdate()- 更新前获取快照componentDidUpdate()- 组件更新后
卸载 (Unmounting)
当组件从 DOM 中移除时:
componentWillUnmount()- 组件卸载前
错误处理 (Error Handling)
当渲染过程、生命周期方法或子组件构造函数中抛出错误时:
static getDerivedStateFromError()- 从错误中恢复componentDidCatch()- 捕获错误
常用生命周期详解
render()
render() 方法是类组件中唯一必须的方法。
render() {
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.state.description}</p>
</div>
);
}⚠️ 注意: render() 应该是纯函数,不应修改 state、 不直接与浏览器交互,应该在 componentDidMount() 中进行这些操作。
constructor(props)
用于初始化状态和绑定事件处理程序。
constructor(props) {
super(props);
// 不要在这里调用 this.setState()
this.state = {
count: 0
};
// 绑定事件处理程序
this.handleClick = this.handleClick.bind(this);
}✅ 最佳实践: 避免在 constructor() 中引入副作用或订阅。 这些操作应该在 componentDidMount() 中进行。
componentDidMount()
在组件挂载后立即调用,是进行副作用操作的最佳位置。
componentDidMount() {
// 数据获取
fetchUserData().then(data => {
this.setState({ user: data });
});
// 订阅
this.subscription = dataSource.subscribe(
this.handleChange
);
}
componentWillUnmount() {
// 清理订阅
this.subscription.unsubscribe();
}componentDidUpdate(prevProps, prevState, snapshot)
在更新后立即调用,首次渲染不会调用。
componentDidUpdate(prevProps) {
// 典型用法:当 props 变化时获取数据
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}⚠️ 注意: 可以在 componentDidUpdate() 中调用 setState(), 但必须包含在条件语句中,否则会导致无限循环。
componentWillUnmount()
在组件卸载和销毁之前立即调用。
componentWillUnmount() {
// 清理定时器
clearInterval(this.timerID);
// 取消网络请求
this.abortController.abort();
// 清理订阅
this.subscription.unsubscribe();
}完整示例
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>当前时间</h1>
<h2>{this.state.date.toLocaleTimeString()}</h2>
</div>
);
}
}最佳实践
✅ 推荐做法
- 使用 setState() 而不是直接修改 state
- 在 componentWillUnmount() 中清理副作用
- 当不需要 state 或生命周期方法时使用函数组件
- 使用 PropTypes 进行类型检查
❌ 避免做法
- 在 render() 中调用 setState()
- 在 constructor() 中进行副作用操作
- 忘记在 componentWillUnmount() 中清理
- 直接修改 this.state
迁移到函数组件
React 推荐使用函数组件和 Hooks 替代类组件。 以下是迁移示例:
类组件
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState(state => ({
count: state.count + 1
}));
}
render() {
return (
<button onClick={this.increment}>
Count: {this.state.count}
</button>
);
}
}函数组件 + Hooks
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(c => c + 1);
};
return (
<button onClick={increment}>
Count: {count}
</button>
);
}