Thời gian đọc: 7 phút
Lifecycle Component trong ReactJS là quá trình một component trải qua từ khi được tạo ra đến khi bị hủy. Nó gồm ba giai đoạn chính: Mounting (gắn kết), Updating (cập nhật), và Unmounting (hủy bỏ). Mỗi giai đoạn có các phương thức đặc trưng như constructor, render, componentDidMount trong Mounting; shouldComponentUpdate, componentDidUpdate trong Updating; và componentWillUnmount trong Unmounting. React cũng cung cấp các phương thức xử lý lỗi như getDerivedStateFromError và componentDidCatch. Hiểu rõ về lifecycle giúp lập trình viên kiểm soát tốt hơn cách component hoạt động, tối ưu hiệu suất và xử lý side effects. Với sự ra đời của Hooks, functional components giờ đây cũng có thể mô phỏng các tính năng lifecycle thông qua useEffect.
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({ count: prevState.count + 1 }));
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
class ExampleComponent extends React.Component {
state = { localCount: 0 };
static getDerivedStateFromProps(props, state) {
if (props.count !== state.localCount) {
return { localCount: props.count };
}
return null;
}
render() {
return <div>Count: {this.state.localCount}</div>;
}
}
class ExampleComponent extends React.Component {
render() {
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.props.content}</p>
</div>
);
}
}
class ExampleComponent extends React.Component {
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
tick() {
this.setState(prevState => ({ time: new Date() }));
}
render() {
return <div>Current time: {this.state.time.toLocaleTimeString()}</div>;
}
}
class ExampleComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return this.props.value !== nextProps.value;
}
render() {
return <div>{this.props.value}</div>;
}
}
class ScrollingList extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>
{this.props.list.map(item => <div key={item.id}>{item.content}</div>)}
</div>
);
}
}
class ExampleComponent extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
fetchData(userID) {
// Giả sử hàm này gọi API để lấy dữ liệu người dùng
}
render() {
return <div>User data for ID: {this.props.userID}</div>;
}
}
class ExampleComponent extends React.Component {
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState(prevState => ({ time: new Date() }));
}
render() {
return <div>Current time: {this.state.time.toLocaleTimeString()}</div>;
}
}
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
Từ React 16.8+, Hooks đã được giới thiệu, cho phép sử dụng state và các tính năng React khác mà không cần viết class. Dưới đây là ví dụ về cách sử dụng useEffect
hook để mô phỏng các lifecycle methods trong functional components:
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
const [count, setCount] = useState(0);
// Tương đương với componentDidMount và componentDidUpdate
useEffect(() => {
document.title = `You clicked ${count} times`;
});
// Tương đương với componentDidMount
useEffect(() => {
const timer = setInterval(() => {
console.log('Timer running');
}, 1000);
// Tương đương với componentWillUnmount
return () => {
clearInterval(timer);
};
}, []); // Empty array means this effect runs once on mount and cleanup on unmount
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Trong ví dụ này, useEffect
được sử dụng để mô phỏng các phương thức lifecycle khác nhau. Hook đầu tiên chạy sau mỗi lần render, trong khi hook thứ hai chỉ chạy một lần khi component mount và cleanup khi unmount.
Lifecycle Component trong ReactJS đóng vai trò quan trọng trong việc quản lý và kiểm soát hành vi của các component trong suốt quá trình tồn tại của chúng. Từ giai đoạn Mounting, qua Updating, đến Unmounting, mỗi giai đoạn cung cấp các phương thức đặc thù cho phép developers can thiệp vào quá trình rendering, cập nhật state và props, thực hiện side effects, và dọn dẹp tài nguyên.
Hiểu rõ về lifecycle giúp lập trình viên tối ưu hiệu suất ứng dụng, xử lý dữ liệu một cách hiệu quả, và tạo ra các component linh hoạt, có khả năng tái sử dụng cao. Đặc biệt, việc nắm vững các phương thức như componentDidMount, shouldComponentUpdate, và componentWillUnmount là chìa khóa để xây dựng các ứng dụng React phức tạp và có hiệu suất cao.
Tuy nhiên, với sự ra đời của React Hooks, cách tiếp cận lifecycle đã có những thay đổi đáng kể. Hooks như useEffect đã mang lại một cách mới để quản lý lifecycle trong functional components, đơn giản hóa code và giảm sự phức tạp. Điều này không có nghĩa là lifecycle trong class components trở nên lỗi thời, mà nó mở ra thêm nhiều lựa chọn cho developers trong việc thiết kế và implement các component.
Trong tương lai, khi React tiếp tục phát triển, chúng ta có thể kỳ vọng vào những cải tiến và tối ưu hóa hơn nữa trong cách quản lý lifecycle. Việc theo dõi và cập nhật kiến thức về những thay đổi này sẽ giúp developers luôn đi đầu trong việc xây dựng các ứng dụng React hiện đại, hiệu quả và dễ bảo trì.
Cuối cùng, dù là sử dụng class components với các phương thức lifecycle truyền thống hay functional components với Hooks, việc hiểu rõ và áp dụng đúng các nguyên tắc của lifecycle sẽ luôn là một kỹ năng quan trọng đối với mọi React developer.