Motion in Production: Hoạt ảnh layout và các pattern dễ tiếp cận
Framer-motion đã thay đổi. Kể từ cuối năm 2024, gói này hiện được gọi là Motion. Bạn phải sử dụng đường dẫn import motion/react.
Hầu hết các hướng dẫn hiện đã lỗi thời. Chúng vẫn hiển thị các cách import cũ và thiếu tính dễ tiếp cận (accessibility). Hướng dẫn này sẽ giúp bạn sử dụng Motion hiện đại trong các dự án thực tế.
Quá trình Nâng cấp
Việc chuyển đổi rất đơn giản. Nếu bạn đang dùng phiên bản 11, việc lên phiên bản 12 chỉ là một thao tác tìm và thay thế (find-and-replace).
- Gỡ cài đặt:
npm uninstall framer-motion - Cài đặt:
npm install motion - Cập nhật import: Thay đổi 'framer-motion' thành 'motion/react'
Bạn có thể chạy cả hai gói cùng lúc trong quá trình di chuyển (migration). Đừng để chúng tồn tại mãi mãi trong mã nguồn của bạn.
Hoạt ảnh Layout
Prop layout yêu cầu Motion theo dõi kích thước và vị trí của một phần tử. Nó sẽ tạo hoạt ảnh cho các thay đổi thay vì để trình duyệt nhảy ngay lập tức đến vị trí mới.
Sử dụng layout="position" cho các danh sách. Điều này giúp di chuyển các phần tử anh em (siblings) khi một mục mở rộng nhưng không làm biến dạng nội dung bên trong.
Sử dụng AnimatePresence cho việc mount và unmount. Nếu không có nó, React sẽ xóa các phần tử khỏi DOM trước khi chúng kịp thực hiện hoạt ảnh biến mất (animate out).
Tránh tạo hoạt ảnh cho height: auto. Nó sẽ gây ra các lỗi hiển thị (visual glitches). Thay vào đó, hãy sử dụng một wrapper CSS grid (từ 0fr đến 1fr) để thay đổi chiều cao một cách mượt mà.
Tính dễ tiếp cận (Accessibility)
Khoảng 30% người dùng iOS bật chế độ prefers-reduced-motion. Đừng chỉ tắt tất cả các hoạt ảnh. Điều này sẽ làm hỏng layout của bạn.
Cách làm sai: Thay thế <motion.div> bằng một thẻ <div> thông thường nếu người dùng muốn giảm chuyển động. Điều này khiến layout bị nhảy đột ngột và tạo cảm giác bị lỗi.
Cách làm đúng: Kiểm soát (gate) quá trình chuyển cảnh, chứ không phải kiểm soát component. Hãy giữ nguyên <motion.div> nhưng đặt duration bằng 0.
Tạo một custom hook để quản lý việc này:
- Sử dụng hook
useReducedMotion. - Nếu là
true, trả vềdurationbằng 0. - Nếu là
false, trả về các thiết lậpspringtiêu chuẩn của bạn.
Điều này đảm bảo các phần tử vẫn đạt đến đúng vị trí của chúng mà không có sự chuyển động.
Khi nào nên dùng Motion
Hãy sử dụng Web Animations API của trình duyệt cho các hiệu ứng mờ dần (fades) đơn giản. Nó không có bất kỳ phụ thuộc (dependencies) nào.
Sử dụng Motion khi bạn cần:
- Các API React-native hiểu được vòng đời (lifecycle) của component.
- Các hoạt ảnh layout có khả năng theo dõi các thay đổi của DOM.
AnimatePresencecho các hoạt ảnh khi thoát (exit animations).- Vật lý lò xo (spring physics) mang lại cảm giác tự nhiên.