Hiển thị flash message khi chuyển trang trong ứng dụng React sử dụng react-router

Tram Ho

Lý thuyết

Hiển thị flash message là một công việc có vẻ khá đơn giản. Chỉ cần một chút code như ví dụ sau là chúng ta đã có thể hoàn thành tính năng này:

Với ví dụ trên, flash message sẽ được hiển thị bên trong ExampleComponent. Tuy nhiên, nó chỉ được hiển thị bên trong ExampleComponent với code điều khiển ẩn/hiện trong component này mà thôi. Nếu chúng ta muốn flash message được hiển thị khi redirect từ một component khác (sử dụng react-router), chẳng hạn như khi tạo dữ liệu thành công ở form nhập liệu, chúng ta redirect về trang hiển thị danh sách dữ liệu và hiển thị flash message ở trang danh sách này thì sao?

Với ứng dụng React dùng react-router, chúng ta dùng

để thực hiện việc redirect đến path được định nghĩa ở các component Route(*). Ngoài tham số path ở trên, hàm push còn có thể nhận 1 tham số nữa là state, đây là object chứa dữ liệu về trạng thái của location. Khi gọi hàm push, location mới chứa pathname, search, hash (được phân tích từ path) và state sẽ được đẩy vào history stack của react-router. Ở component được redirect đến, location của component này chính là location mới vừa được đẩy vào history stack đó.

Như vậy, chúng ta có thể lợi dụng việc này để gán flash message vào state, khi hiển thị component được redirect đến thì lấy dữ liệu flash message ở state của location ra và hiển thị.

(*) hàm history.push còn có thể nhận một tham số là object chứa các dữ liệu về pathname, searchstate như sau:

Ví dụ

Để minh họa, chúng ta sẽ làm một ứng dụng React ví dụ có các chức năng tạo và hiển thị danh sách ghi chú. Khi tạo ghi chú thành công, ứng dụng sẽ redirect về trang danh sách ghi chú và hiển thị flash message thông báo tạo ghi chú thành công ở trên trang danh sách này.

Thêm + hiển thị danh sách ghi chú

Tạo project mới bằng create-react-app, sau đó di chuyển vào thư mục này:

Thêm css của bootstrap vào file public/index.html:

Thêm package react-router-dom:

Tạo file src/NoteForm.jsx chứa form tạo ghi chú. Form gồm một textarea dùng để nhập nội dung ghi chú và một nút submit. Khi submit form, hàm addNote truyền từ props sẽ được dùng để tạo ghi chú, tạo xong sẽ redirect về /.

Tạo file src/Notes.jsx chứa component hiển thị danh sách ghi chú lấy từ notes của props. Ghi chú gồm nội dung và thời gian tạo.

Sửa lại file src/App.js. App mới sẽ có

  • state notes chứa các ghi chú đã được tạo. notes sẽ được truyền vào component Notes.
  • hàm addNote dùng để thêm ghi chú mới vào notes. Hàm này sẽ được truyền vào component NoteForm.
  • các route khai báo đường link và component tương ứng. / ứng với component Notes, /create_note ứng với NoteForm.
  • các hàm tiện ích để tạo giá trị createdAt cho ghi chú khi tạo ghi chú.

Thêm css vào file src/index.css:

Chạy ứng dụng bằng lệnh yarn start. Chúng ta có thể tạo ghi chú, tuy nhiên chưa có flash message khi redirect về trang danh sách ghi chú. Chúng ta sẽ thêm flash message ở bước sau.

Thêm flash message

Tạo file src/FlashMessage.jsx chứa component FlashMessage:

Tại file src/Notes.jsx, lấy flashMessage trong state của location ra và hiển thị:

Tại hàm submitForm của NoteForm, truyền thêm state khi redirect về /:

Lúc này, khi tạo note xong và redirect về / thì flash message với nội dung Create note successfully! sẽ xuất hiện.

Sửa lỗi khi nhấn nút Back trên trình duyệt

Sau khi tạo xong ghi chú và redirect về /, chuyển sang form tạo ghi chú thì flash message sẽ biến mất. Nhưng nếu tiếp đó bạn nhấn vào nút Back trên trình duyệt thì trang danh sách ghi chú sẽ hiện lại và flash message lại hiện ra tiếp.

Nguyên nhân của việc này là do react-router lấy location cũ từ stack ra và location này vẫn chứa flashMessage trong state của nó. Component Notes sẽ chạy lại đoạn code lấy flashMessage từ state của location và hiển thị lại flashMessage này.

Để flash message không hiển thị lại như vậy, chúng ta sẽ xóa luôn flashMessage trong state của location khi lấy nó ra. Sửa lại src/Notes.jsx như sau:

Thử lại trường hợp nhấn nút Back ở trên, flash message sẽ không hiện lại nữa.

Chuyển code xử lý flash message vào hook

Để tiện cho việc tái sử dụng, chúng ta có thể chuyển đoạn code xử lý flash message trong component Notes vào hook useFlashMessage. Các component khác có thể sử dụng hook này để lấy flashMessage từ location và hiển thị.

Tạo file src/use_flash_message.jsx với nội dung như sau:

Hook useFlashMessage sẽ trả về hàm flashMessageComponent, chúng ta có thể dùng hàm này như một component để hiển thị flash message. Sửa lại src/Notes.jsx:

Mở rộng: chúng ta có thể trả về thêm flashMessage, setFlashMessage từ useFlashMessage để tùy ý sử dụng, ví dụ như dùng setFlashMessage để hiển thị flashMessage với nội dung mới ngay tại trang hiện tại.

Kết luận

Qua lý thuyết và ví dụ được trình bày ở trên, hi vọng các bạn đang gặp vướng mắc khi hiển thị flash message lúc chuyển trang có thể tham khảo vào giải quyết vấn đề một cách suôn sẻ. Cảm ơn các bạn đã theo dõi bài viết.

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo