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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Alert<span class="token punctuation">,</span> Button <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'reactstrap'</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function-variable function">ExampleComponent</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>isFlashMessageShown<span class="token punctuation">,</span> setIsFlashMessageShown<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">showFlashMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setIsFlashMessageShown</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">hideFlashMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setIsFlashMessageShown</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Alert</span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>primary<span class="token punctuation">'</span></span> <span class="token attr-name">isOpen</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>isFlashMessageShown<span class="token punctuation">}</span></span> <span class="token attr-name">toggle</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>hideFlashMessage<span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> Hello there! </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Alert</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Button</span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>primary<span class="token punctuation">'</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>showFlashMessage<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> Show flash message </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Button</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
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
1 2 | history<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> |
để 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
, search
và state
như sau:
1 2 3 4 5 6 | history<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> pathname<span class="token punctuation">:</span> <span class="token string">'/posts'</span><span class="token punctuation">,</span> search<span class="token punctuation">:</span> <span class="token string">'?category=game'</span> state<span class="token punctuation">:</span> <span class="token punctuation">{</span> redirectFrom<span class="token punctuation">:</span> <span class="token string">'/redirected_path'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
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:
1 2 3 | create-react-app flash-message cd flash-message |
Thêm css của bootstrap vào file public/index.html
:
1 2 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css<span class="token punctuation">"</span></span> <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T<span class="token punctuation">"</span></span> <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> |
Thêm package react-router-dom
:
1 2 | yarn add 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ề /
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> withRouter <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">NoteForm</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> history<span class="token punctuation">,</span> addNote <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>content<span class="token punctuation">,</span> setContent<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">submitForm</span> <span class="token operator">=</span> event <span class="token operator">=></span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addNote</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> history<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>row mt-5<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>col-md-10 offset-md-1<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h4</span><span class="token punctuation">></span></span><span class="token plain-text">Add Note</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h4</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span> <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>submitForm<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>form-group<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>textarea</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>content<span class="token punctuation">'</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>form-control<span class="token punctuation">'</span></span> <span class="token attr-name">rows</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>10<span class="token punctuation">'</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>Enter content<span class="token punctuation">'</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>e <span class="token operator">=></span> <span class="token function">setContent</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>form-group<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>submit<span class="token punctuation">'</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>btn btn-primary<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text">Submit</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">withRouter</span><span class="token punctuation">(</span>NoteForm<span class="token punctuation">)</span><span class="token punctuation">;</span> |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Fragment <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">Notes</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> notes <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Fragment</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>mt-5<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>row<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>col-md-10 offset-md-1<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h4</span><span class="token punctuation">></span></span><span class="token plain-text">Notes</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h4</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>text-center<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Link</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>btn btn-primary<span class="token punctuation">'</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>/create_note<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> Create note </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Link</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>row mt-4<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>col-md-10 offset-md-1<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>notes<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span> notes<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>note<span class="token punctuation">,</span> index<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>note<span class="token punctuation">'</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>note-content<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>content<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>note-createdAt<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>createdAt<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Fragment</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> Notes<span class="token punctuation">;</span> |
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 componentNotes
. - hàm
addNote
dùng để thêm ghi chú mới vàonotes
. Hàm này sẽ được truyền vào componentNoteForm
. - các route khai báo đường link và component tương ứng.
/
ứng với componentNotes
,/create_note
ứng vớiNoteForm
. - các hàm tiện ích để tạo giá trị
createdAt
cho ghi chú khi tạo ghi chú.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> BrowserRouter <span class="token keyword">as</span> Router<span class="token punctuation">,</span> Switch<span class="token punctuation">,</span> Route<span class="token punctuation">,</span> Link<span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Notes <span class="token keyword">from</span> <span class="token string">'./Notes'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> NoteForm <span class="token keyword">from</span> <span class="token string">'./NoteForm'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">zeroPadded</span> <span class="token operator">=</span> num <span class="token operator">=></span> num <span class="token operator"><</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token template-string"><span class="token string">`0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>num<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span> <span class="token punctuation">:</span> num<span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">timestamp</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> time <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> year <span class="token operator">=</span> time<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> month <span class="token operator">=</span> <span class="token function">zeroPadded</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> day <span class="token operator">=</span> <span class="token function">zeroPadded</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> hour <span class="token operator">=</span> <span class="token function">zeroPadded</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> minute <span class="token operator">=</span> <span class="token function">zeroPadded</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> second <span class="token operator">=</span> <span class="token function">zeroPadded</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>year<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>month<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>day<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hour<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>minute<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>second<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">App</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>notes<span class="token punctuation">,</span> setNotes<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">addNote</span> <span class="token operator">=</span> content <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> newNote <span class="token operator">=</span> <span class="token punctuation">{</span> content<span class="token punctuation">,</span> createdAt<span class="token punctuation">:</span> <span class="token function">timestamp</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">setNotes</span><span class="token punctuation">(</span><span class="token punctuation">[</span>newNote<span class="token punctuation">,</span> <span class="token operator">...</span>notes<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Router</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>container<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>header</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>header<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ul</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>nav<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>nav-item<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Link</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>nav-link active<span class="token punctuation">'</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>/<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text">Notes</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Link</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Switch</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Route</span> <span class="token attr-name">exact</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>/create_note<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>NoteForm</span> <span class="token attr-name">addNote</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>addNote<span class="token punctuation">}</span></span><span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Route</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Route</span> <span class="token attr-name">exact</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>/<span class="token punctuation">'</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Notes</span> <span class="token attr-name">notes</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>notes<span class="token punctuation">}</span></span><span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Route</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Switch</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Router</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> App<span class="token punctuation">;</span> |
Thêm css vào file src/index.css
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token selector">.header</span> <span class="token punctuation">{</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid gray<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.notes</span> <span class="token punctuation">{</span> <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">padding-left</span><span class="token punctuation">:</span> 0px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.note</span> <span class="token punctuation">{</span> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid <span class="token function">rgba</span><span class="token punctuation">(</span>0, 0, 0, 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.note-content</span> <span class="token punctuation">{</span> <span class="token property">white-space</span><span class="token punctuation">:</span> pre-wrap<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.note-createdAt</span> <span class="token punctuation">{</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 0.7em<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 0px<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span> <span class="token punctuation">}</span> |
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
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">FlashMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> flashMessage<span class="token punctuation">,</span> close <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> type<span class="token punctuation">,</span> message <span class="token punctuation">}</span> <span class="token operator">=</span> flashMessage<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>message<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token string">`alert alert-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>type<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>button<span class="token punctuation">'</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">'</span>close<span class="token punctuation">'</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>close<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span><span class="token punctuation">></span></span><span class="token plain-text">&times;</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>message<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> FlashMessage<span class="token punctuation">;</span> |
Tại file src/Notes.jsx
, lấy flashMessage
trong state
của location
ra và hiển thị:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <span class="token comment">// import thêm useState</span> <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Fragment<span class="token punctuation">,</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token comment">// import thêm withRouter</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> withRouter<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span><span class="token punctuation">;</span> <span class="token comment">// import thêm FlashMessage</span> <span class="token keyword">import</span> FlashMessage <span class="token keyword">from</span> <span class="token string">'./FlashMessage'</span><span class="token punctuation">;</span> <span class="token comment">// lấy thêm location từ props</span> <span class="token keyword">const</span> <span class="token function-variable function">Notes</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> location<span class="token punctuation">,</span> notes <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// lấy flashMessage ra từ state của location</span> <span class="token comment">// nếu không có thì gán bằng object rỗng</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> flashMessage<span class="token punctuation">:</span> fm <span class="token punctuation">}</span> <span class="token operator">=</span> location<span class="token punctuation">.</span>state <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> redirectedFlashMessage <span class="token operator">=</span> fm <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>flashMessage<span class="token punctuation">,</span> setFlashMessage<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span>redirectedFlashMessage<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Fragment</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token comment">/* hiển thị flash message */</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>FlashMessage</span> <span class="token attr-name">flashMessage</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>flashMessage<span class="token punctuation">}</span></span> <span class="token attr-name">close</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setFlashMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> ... </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Fragment</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// gói Notes trong higher order component withRouter</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">withRouter</span><span class="token punctuation">(</span>Notes<span class="token punctuation">)</span><span class="token punctuation">;</span> |
Tại hàm submitForm
của NoteForm
, truyền thêm state
khi redirect về /
:
1 2 3 4 5 6 7 8 | <span class="token keyword">const</span> <span class="token function-variable function">submitForm</span> <span class="token operator">=</span> event <span class="token operator">=></span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addNote</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> history<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> flashMessage<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> <span class="token string">'success'</span><span class="token punctuation">,</span> message<span class="token punctuation">:</span> <span class="token string">'Create note successfully!'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token comment">// import thêm history</span> <span class="token keyword">const</span> <span class="token function-variable function">Notes</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> history<span class="token punctuation">,</span> location<span class="token punctuation">,</span> notes <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> redirectedFlashMessage <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> pathname<span class="token punctuation">,</span> search<span class="token punctuation">,</span> state <span class="token punctuation">}</span> <span class="token operator">=</span> location<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state <span class="token operator">&&</span> state<span class="token punctuation">.</span>flashMessage<span class="token punctuation">)</span> <span class="token punctuation">{</span> redirectedFlashMessage <span class="token operator">=</span> state<span class="token punctuation">.</span>flashMessage<span class="token punctuation">;</span> <span class="token comment">// copy state cũ</span> <span class="token keyword">const</span> clonedState <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>state <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// xóa flashMessage từ state được copy</span> <span class="token keyword">delete</span> clonedState<span class="token punctuation">.</span>flashMessage<span class="token punctuation">;</span> <span class="token comment">// thay thế location hiện tại bằng location mới</span> <span class="token comment">// với pathname, search từ location hiện tại</span> <span class="token comment">// và state đã xóa flashMessage</span> history<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token punctuation">{</span> pathname<span class="token punctuation">,</span> search<span class="token punctuation">,</span> state<span class="token punctuation">:</span> clonedState <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">...</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> FlashMessage <span class="token keyword">from</span> <span class="token string">'./FlashMessage'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">useFlashMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span>location<span class="token punctuation">,</span> history<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> redirectedFlashMessage <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> pathname<span class="token punctuation">,</span> search<span class="token punctuation">,</span> state <span class="token punctuation">}</span> <span class="token operator">=</span> location<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state <span class="token operator">&&</span> state<span class="token punctuation">.</span>flashMessage<span class="token punctuation">)</span> <span class="token punctuation">{</span> redirectedFlashMessage <span class="token operator">=</span> state<span class="token punctuation">.</span>flashMessage<span class="token punctuation">;</span> <span class="token keyword">const</span> clonedState <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>state <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> clonedState<span class="token punctuation">.</span>flashMessage<span class="token punctuation">;</span> history<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token punctuation">{</span> pathname<span class="token punctuation">,</span> search<span class="token punctuation">,</span> state<span class="token punctuation">:</span> clonedState <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>flashMessage<span class="token punctuation">,</span> setFlashMessage<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span>redirectedFlashMessage<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">flashMessageComponent</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>FlashMessage</span> <span class="token attr-name">flashMessage</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>flashMessage<span class="token punctuation">}</span></span> <span class="token attr-name">close</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setFlashMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> flashMessageComponent<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> useFlashMessage<span class="token punctuation">;</span> |
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
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Fragment<span class="token punctuation">,</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> withRouter<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span><span class="token punctuation">;</span> <span class="token comment">// bỏ import FlashMessage</span> <span class="token comment">// import useFlashMessage</span> <span class="token keyword">import</span> useFlashMessage <span class="token keyword">from</span> <span class="token string">'./use_flash_message'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">Notes</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> history<span class="token punctuation">,</span> location<span class="token punctuation">,</span> notes <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> FlashMessage <span class="token operator">=</span> <span class="token function">useFlashMessage</span><span class="token punctuation">(</span>location<span class="token punctuation">,</span> history<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>Fragment</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token comment">/* sửa lại code hiển thị flash message */</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>FlashMessage</span> <span class="token punctuation">/></span></span><span class="token plain-text"> ... </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>Fragment</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">withRouter</span><span class="token punctuation">(</span>Notes<span class="token punctuation">)</span><span class="token punctuation">;</span> |
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.