TL;DR: Cách khắc phục nhanh
Hãy ngừng sử dụng thuộc tính Component.defaultProps. Thay vào đó, hãy đưa các giá trị mặc định trực tiếp vào chữ ký hàm (function signature) bằng cú pháp JavaScript tiêu chuẩn.
Trước đây:
function Button({ label, color }) {
return <button style={{ color }}>{label}</button>;
}
Button.defaultProps = {
color: 'blue',
label: 'Nhấn vào đây'
};
Sau khi sửa:
function Button({ label = 'Nhấn vào đây', color = 'blue' }) {
return <button style={{ color }}>{label}</button>;
}
Tại sao React lại thực hiện thay đổi này?
React 18.3 đóng vai trò là cầu nối tới phiên bản 19. Nó đưa ra cảnh báo này để các nhà phát triển có thời gian cấu trúc lại mã nguồn (refactor) trước khi tính năng này chính thức bị loại bỏ. Đội ngũ React đang tinh giản thư viện bằng cách loại bỏ các mẫu (pattern) dư thừa. Vì tham số mặc định ES6 hiện đã là tiêu chuẩn trong JavaScript, việc duy trì defaultProps dành riêng cho React trong function component không còn hợp lý nữa.
Tham số mặc định thuần túy (native defaults) hiệu quả hơn. Chúng giúp giảm bớt gánh nặng quản lý cho React và giúp các IDE như VS Code phân tích mã của bạn dễ dàng hơn. Lưu ý rằng thay đổi này chỉ ảnh hưởng đến function component. Class component vẫn sẽ tiếp tục hỗ trợ defaultProps trong tương lai gần.
Cấu trúc lại các mẫu phổ biến
1. Destructuring tiêu chuẩn
Hầu hết các component hiện đại đã sử dụng destructuring cho props. Nếu bạn chưa làm điều này, đây là thời điểm hoàn hảo để bắt đầu. Nó giúp các phụ thuộc (dependencies) của component trở nên rõ ràng ngay từ cái nhìn đầu tiên.
// ❌ Cách cũ
const UserProfile = (props) => {
return <div>{props.name}</div>;
};
UserProfile.defaultProps = { name: 'Khách' };
// ✅ Cách mới
const UserProfile = ({ name = 'Khách' }) => {
return <div>{name}</div>;
};
2. Làm việc với TypeScript
Khi sử dụng TypeScript, hãy đánh dấu các props của bạn là tùy chọn trong interface bằng toán tử ?. Sau đó, gán giá trị mặc định trong quá trình destructuring. Điều này đảm bảo các kiểu dữ liệu (types) của bạn luôn chính xác trong khi vẫn đáp ứng các yêu cầu mới của React.
interface Props {
title?: string;
isAdmin?: boolean;
}
const Header = ({ title = 'Chào mừng', isAdmin = false }: Props) => {
return (
<header>
<h1>{title}</h1>
{isAdmin && <span>Bảng điều khiển Admin</span>}
</header>
);
};
3. Xử lý forwardRef và memo
Các Higher-Order Components (HOCs) như React.memo hoặc forwardRef thường khiến nhiều người lúng túng. Cách khắc phục vẫn tương tự: giữ các giá trị mặc định bên trong chữ ký hàm nội bộ nơi props thực sự được nhận.
const CustomInput = React.forwardRef(({ type = 'text', placeholder = 'Nhập văn bản...' }, ref) => {
return <input ref={ref} type={type} placeholder={placeholder} />;
});
Nếu lỗi nằm ở một thư viện thì sao?
Bạn có thể thấy cảnh báo này ngay cả khi mã của chính bạn đã hoàn hảo. Các thư viện nổi tiếng như Recharts, Material UI (phiên bản cũ), và React Bootstrap trước đây thường dựa vào defaultProps. Thực tế, người dùng Recharts đã gặp lỗi này thường xuyên cho đến phiên bản 2.13.0.
- Cập nhật ngay lập tức: Chạy lệnh
npm update. Hầu hết các nhà duy trì (maintainers) đã phát hành các bản vá để tương thích với React 19. - Xác định nguyên nhân: Nhìn vào tên component trong cảnh báo. Nếu đó là những cái tên như
<XAxis>hoặc<ResponsiveContainer>, vấn đề nằm trong thư mụcnode_modulescủa bạn. - Chờ đợi hoặc vá lỗi: Nếu thư viện đó không còn được bảo trì, bạn có thể cần sử dụng
patch-packagehoặc chuyển sang một giải pháp thay thế hiện đại hơn trước khi nâng cấp lên React 19.
Cách xác minh bản sửa lỗi
- Làm mới trong Chế độ Phát triển: Những cảnh báo này chỉ xuất hiện ở chế độ phát triển (development mode). Hãy tải lại trình duyệt và theo dõi console.
- Kiểm tra các trình kích hoạt cụ thể: Điều hướng đến route cụ thể nơi component đó render. Một số cảnh báo chỉ xuất hiện khi component thực sự được mount.
- Kiểm tra việc ghi đè Props: Đảm bảo rằng việc truyền prop thủ công vẫn ghi đè được giá trị mặc định mới của bạn. Ví dụ,
<Button color="red" />vẫn phải hiển thị màu đỏ, chứ không phải màu xanh mặc định.

