Ví dụ về lỗi sử dụng React Hook Form với Controller không nhận được FormProvider
Trong quá trình phát triển ứng dụng, một lỗi phổ biến xảy ra khi dùng React Hook Form với Controller mà không nhận được FormProvider từ bên ngoài, đặc biệt khi hai thành phần nằm ở các vị trí khác nhau trong dự án.
Tình huống cụ thể
Cấu trúc dự án:
- apps/route: Chứa file sử dụng React Hook Form.
- libs/ui: Chứa các thành phần giao diện, bao gồm thư mục form control với thành phần CustomInput sử dụng
Controller
.
Quy trình triển khai:
- Trong thư mục libs/ui, chúng ta tạo thành phần
CustomInput
và build thành một package với tên là @myproject/ui. - Trong apps/route, cài đặt package @myproject/ui từ libs/ui thông qua file
package.json
. - Trong apps/route, tạo file
uploadfile
để sử dụng biểu mẫu từ React Hook Form. Tại đây, chúng ta sử dụnguseForm
và truyền FormProvider xuống các thành phần con, bao gồm CustomInput.
Lỗi gặp phải
Khi chạy ứng dụng, thành phần CustomInput không nhận được formContext từ FormProvider. Kết quả là React Hook Form báo lỗi:
Nguyên nhân lỗi
Nguyên nhân chính nằm ở cách quản lý React và các package liên quan trong hệ thống node_modules:
- React trong @myproject/ui và apps/route không đồng bộ, dẫn đến việc tạo hai phiên bản React độc lập trong dự án.
- Hai phiên bản này gây ra lỗi khi truyền context từ FormProvider xuống CustomInput.
Giải pháp: Cấu hình Webpack để dùng chung package React
Để giải quyết vấn đề, chúng ta cần cấu hình Webpack trong file razzle.config.js
của apps/route để đảm bảo sử dụng chung các package như React và React-DOM.
Cấu hình razzle.config.js
const path = require('path'); const root = path.resolve(__dirname, '.', 'node_modules'); module.exports = { modifyWebpackConfig({ webpackConfig }) { webpackConfig.resolve.alias = { ...webpackConfig.resolve.alias, react: path.resolve(root, 'react'), // Chỉ định đường dẫn tới React trong node_modules chung 'react-dom': path.resolve(root, 'react-dom'), // Chỉ định đường dẫn tới React-DOM }; return webpackConfig; }, };
Giải thích cấu hình
path.resolve(root, 'react')
: Đảm bảo cả apps/route và libs/ui đều sử dụng cùng một phiên bản React từ thư mụcnode_modules
gốc.- Tương tự,
path.resolve(root, 'react-dom')
giúp đồng bộ React-DOM.
Lợi ích
- Đảm bảo các context, như formContext, được truyền chính xác giữa các thành phần.
- Tránh việc tải nhiều phiên bản React, giúp giảm kích thước gói build và tăng hiệu suất.
Kết luận
Việc cấu hình Webpack để sử dụng chung package là giải pháp quan trọng trong các dự án monorepo hoặc khi sử dụng pnpm. Điều này không chỉ giải quyết lỗi React Hook Form mà còn cải thiện hiệu năng tổng thể của ứng dụng.
Xem thêm: Thêm Pipeline tùy chỉnh vào trong ICalculateCartPipeline.