Giới thiệu
React là một thư viện front-end phổ biến, dễ học và dễ sử dụng. Tuy nhiên, có một số khái niệm mà các nhà phát triển nên hiểu để viết mã hiệu quả và hiệu quả. Trong bài viết này, chúng ta sẽ thảo luận về một số vấn đề và khái niệm liên quan đến cách thức hoạt động của trạng thái và hiệu ứng trong React.
Bắt nguồn từ Nhà nước
Đôi khi, chúng ta cần tạo một biến trạng thái phụ thuộc vào một biến trạng thái khác. Một cách để làm điều này là sử dụng hook useEffect
và cập nhật biến trạng thái phụ thuộc vào biến trạng thái khác.
Ví dụ: giả sử chúng ta có một thành phần select
hiển thị danh sách ID người dùng. Chúng tôi muốn theo dõi ID người dùng đã chọn bằng biến trạng thái userId
. Đây là cách chúng ta có thể làm điều này:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">import</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 keyword">const</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token string">"1"</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"User One"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token string">"2"</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"User Two"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> id <span class="token operator">:</span> <span class="token string">"3"</span> <span class="token punctuation">,</span> name <span class="token operator">:</span> <span class="token string">"User Three"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token keyword">function</span> <span class="token function">Users</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> userId <span class="token punctuation">,</span> setUserId <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">"1"</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> select</span> <span class="token attr-name">value</span> <span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span> <span class="token punctuation">{</span> userId <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> <span class="token parameter">e</span> <span class="token operator">=></span> <span class="token function">setUserId</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 tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 1 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User One</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 2 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Two</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 3 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Three</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> select</span> <span class="token punctuation">></span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Bây giờ, giả sử chúng ta muốn hiển thị người dùng đã chọn trên màn hình. Chúng ta có thể tạo một biến trạng thái khác có tên là selectedUser
và cập nhật nó bất cứ khi nào userId
thay đổi bằng cách sử dụng hook useEffect
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">,</span> useEffect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"react"</span> <span class="token keyword">function</span> <span class="token function">Users</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> userId <span class="token punctuation">,</span> setUserId <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 keyword">const</span> <span class="token punctuation">[</span> selectedUser <span class="token punctuation">,</span> setSelectedUser <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token keyword">undefined</span> <span class="token punctuation">)</span> <span class="token function">useEffect</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 function">setSelectedUser</span> <span class="token punctuation">(</span> users <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token parameter">u</span> <span class="token operator">=></span> u <span class="token punctuation">.</span> id <span class="token operator">===</span> userId <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> userId <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></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> select</span> <span class="token attr-name">value</span> <span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span> <span class="token punctuation">{</span> userId <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> <span class="token parameter">e</span> <span class="token operator">=></span> <span class="token function">setUserId</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 tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token punctuation">></span></span> <span class="token plain-text">Select a user</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 1 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User One</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 2 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Two</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 3 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Three</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> select</span> <span class="token punctuation">></span></span> <span class="token punctuation">{</span> selectedUser <span class="token operator">&&</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">The selected user is: </span><span class="token punctuation">{</span> selectedUser <span class="token punctuation">.</span> name <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 punctuation">}</span> <span class="token tag"><span class="token tag"><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 punctuation">}</span> |
Cách tiếp cận này hoạt động, nhưng nó không phải là cách hiệu quả nhất để cập nhật selectedUser
. Vấn đề với phương pháp này là thành phần đầu tiên hiển thị khi userId
thay đổi và sau đó hook useEffect
được kích hoạt sau khi kết xuất vì userId được chuyển vào mảng phụ thuộc của nó. Điều này có nghĩa là thành phần hiển thị hai lần chỉ để cập nhật selectedUser
, lần đầu tiên khi userId
thay đổi và lần thứ hai khi hook useEffect cập nhật selectedUser
.
Cách tiếp cận tốt hơn là chỉ cần lấy trực tiếp giá trị của selectedUser
từ userId
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">function</span> <span class="token function">Users</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> userId <span class="token punctuation">,</span> setUserId <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 keyword">const</span> selectedUser <span class="token operator">=</span> users <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token parameter">u</span> <span class="token operator">=></span> u <span class="token punctuation">.</span> id <span class="token operator">===</span> userId <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></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> select</span> <span class="token attr-name">value</span> <span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span> <span class="token punctuation">{</span> userId <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> <span class="token parameter">e</span> <span class="token operator">=></span> <span class="token function">setUserId</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 tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token punctuation">></span></span> <span class="token plain-text">Select a user</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 1 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User One</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 2 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Two</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> option</span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> 3 <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">User Three</span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> option</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> select</span> <span class="token punctuation">></span></span> <span class="token punctuation">{</span> selectedUser <span class="token operator">&&</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">The selected user is: </span><span class="token punctuation">{</span> selectedUser <span class="token punctuation">.</span> name <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 punctuation">}</span> <span class="token tag"><span class="token tag"><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 punctuation">}</span> |
Điều này hoạt động vì người dùng selectedUser
được lấy trực tiếp từ userId và không được theo dõi dưới dạng một biến trạng thái riêng biệt. Điều này có nghĩa là thành phần sẽ chỉ hiển thị lại khi userId thay đổi, thay vì hiển thị lại hai lần như trong ví dụ trước.
Đặt trạng thái bên trong Trình xử lý sự kiện
Đôi khi, chúng ta cần cập nhật trạng thái bên trong trình xử lý sự kiện, chẳng hạn như sự kiện nhấp chuột hoặc sự kiện gửi biểu mẫu. Trong những trường hợp này, điều quan trọng là đảm bảo rằng cập nhật trạng thái được thực hiện không đồng bộ để thành phần có cơ hội kết xuất lại trước khi trình xử lý sự kiện kết thúc thực thi.
Dưới đây là một ví dụ về cách thiết lập chính xác trạng thái bên trong trình xử lý sự kiện:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">function</span> <span class="token function">Counter</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> count <span class="token punctuation">,</span> setCount <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">handleClick</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 function">setCount</span> <span class="token punctuation">(</span> count <span class="token operator">+</span> <span class="token number">1</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 punctuation">></span></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">The count is: </span><span class="token punctuation">{</span> count <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 tag"><span class="token tag"><span class="token punctuation"><</span> button</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> handleClick <span class="token punctuation">}</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">Increment</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 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> |
Trong ví dụ này, chúng ta có một thành phần Counter
hiển thị số đếm và có một nút tăng số đếm khi được nhấp. Trình xử lý sự kiện handleClick
cập nhật biến trạng thái count
bằng hàm setCount
.
Điều quan trọng cần lưu ý là hàm setCount
không đồng bộ, có nghĩa là cập nhật trạng thái có thể không được phản ánh ngay lập tức trong thành phần. Thay vào đó, thành phần sẽ kết xuất lại sau khi trình xử lý sự kiện kết thúc thực thi.
Nếu chúng ta cần thực hiện một thao tác phụ thuộc vào giá trị hiện tại của trạng thái, chúng ta có thể chuyển một hàm cho hàm setCount
, như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">function</span> <span class="token function">Counter</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> count <span class="token punctuation">,</span> setCount <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">handleClick</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 function">setCount</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token parameter">currentCount</span> <span class="token punctuation">)</span> <span class="token operator">=></span> currentCount <span class="token operator">+</span> <span class="token number">1</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 punctuation">></span></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">The count is: </span><span class="token punctuation">{</span> count <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 tag"><span class="token tag"><span class="token punctuation"><</span> button</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> handleClick <span class="token punctuation">}</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">Increment</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 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> |
Trong ví dụ này, hàm setCount
được gọi với một hàm lấy giá trị hiện tại của count
làm đối số và trả về giá trị mới. Điều này đảm bảo rằng cập nhật trạng thái được thực hiện chính xác, ngay cả khi thành phần chưa có cơ hội kết xuất lại.
chức năng dọn dẹp
Đôi khi, chúng ta cần thực hiện một số hành động dọn dẹp khi một thành phần không được đếm hoặc khi một điều kiện nhất định không còn được đáp ứng. Trong những trường hợp này, chúng ta có thể sử dụng chức năng dọn dẹp với hook useEffect
.
Hàm dọn dẹp là một hàm được gọi khi một thành phần không được đếm hoặc khi các thành phần phụ thuộc của hook useEffect
thay đổi. Đó là một nơi tốt để thực hiện bất kỳ công việc dọn dẹp cần thiết nào, chẳng hạn như hủy yêu cầu mạng hoặc xóa trình lắng nghe sự kiện.
Dưới đây là một ví dụ về cách sử dụng chức năng dọn dẹp với hook useEffect
:
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 | <span class="token keyword">function</span> <span class="token function">Users</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> userId <span class="token punctuation">,</span> setUserId <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">[</span> user <span class="token punctuation">,</span> setUser <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">useEffect</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 keyword">const</span> <span class="token function-variable function">fetchUser</span> <span class="token operator">=</span> <span class="token keyword">async</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> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">/users/</span> <span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> userId <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token keyword">await</span> response <span class="token punctuation">.</span> <span class="token function">json</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setUser</span> <span class="token punctuation">(</span> data <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token function">fetchUser</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 punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Cleanup function</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Cleaning up..."</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> <span class="token punctuation">[</span> userId <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 punctuation">></span></span> <span class="token punctuation">{</span> user <span class="token operator">?</span> <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">The user is: </span><span class="token punctuation">{</span> user <span class="token punctuation">.</span> name <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 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> p</span> <span class="token punctuation">></span></span> <span class="token plain-text">Loading...</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 punctuation">)</span> <span class="token punctuation">}</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</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> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setUserId</span> <span class="token punctuation">(</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">Load User 2</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 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> |
Trong ví dụ này, chúng tôi có thành phần Users
tìm nạp người dùng từ API phụ trợ dựa trên biến trạng thái userId
. useEffect
được sử dụng để kích hoạt tìm nạp khi userId
thay đổi.
useEffect
cũng có chức năng dọn dẹp được gọi khi thành phần không được đếm hoặc khi biến trạng thái userId
thay đổi. Trong trường hợp này, chức năng dọn dẹp chỉ cần ghi một thông báo vào bảng điều khiển.
Điều quan trọng cần lưu ý là chức năng dọn dẹp chỉ được gọi khi phần phụ thuộc của hook useEffect
thay đổi hoặc khi thành phần không được đếm. Điều này có nghĩa là nếu biến trạng thái userId
thay đổi nhưng phần phụ thuộc của hook useEffect
thì không, hàm dọn dẹp sẽ không được gọi.
Cập nhật Trạng thái khi Prop thay đổi
Đôi khi, chúng ta cần cập nhật trạng thái của một thành phần dựa trên một chỗ dựa được truyền cho thành phần đó. Trong những trường hợp này, chúng ta có thể sử dụng hook useEffect
để phát hiện khi prop thay đổi và cập nhật trạng thái tương ứng.
Đây là một ví dụ về cách cập nhật trạng thái khi prop thay đổi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">function</span> <span class="token function">User</span> <span class="token punctuation">(</span> <span class="token parameter"><span class="token punctuation">{</span> userId <span class="token punctuation">}</span></span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span> user <span class="token punctuation">,</span> setUser <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">useEffect</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 keyword">const</span> <span class="token function-variable function">fetchUser</span> <span class="token operator">=</span> <span class="token keyword">async</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> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">/users/</span> <span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> userId <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token keyword">await</span> response <span class="token punctuation">.</span> <span class="token function">json</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setUser</span> <span class="token punctuation">(</span> data <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token function">fetchUser</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> userId <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> user <span class="token operator">?</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">The user is: </span><span class="token punctuation">{</span> user <span class="token punctuation">.</span> name <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 operator">:</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">Loading...</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 punctuation">;</span> <span class="token punctuation">}</span> |
Trong ví dụ này, chúng tôi có một thành phần User
tìm nạp người dùng từ API phụ trợ dựa trên userId
prop. useEffect
được sử dụng để kích hoạt tìm nạp khi prop userId
thay đổi.
Điều quan trọng cần lưu ý là mảng phụ thuộc của useEffect
hook phải bao gồm bất kỳ props hoặc biến trạng thái nào mà hiệu ứng phụ thuộc vào. Trong trường hợp này, hiệu ứng phụ thuộc vào userId
prop, vì vậy nó được bao gồm trong mảng phụ thuộc.
Nếu các thành phần phụ thuộc của hook useEffect
không được chỉ định chính xác, thì hiệu ứng có thể được kích hoạt một cách không cần thiết, điều này có thể dẫn đến các vấn đề về hiệu suất.
Bảo quản nhà nước ở cùng một vị trí
Đôi khi, chúng ta cần giữ nguyên trạng thái của một thành phần khi nó được kết xuất lại ở cùng một vị trí trên trang. Trong những trường hợp này, chúng ta có thể sử dụng hook useState
với hook useMemo
để duy trì trạng thái.
useMemo
hook là một tối ưu hóa hiệu suất cho phép chúng ta ghi nhớ các giá trị để chúng chỉ được tính toán lại khi các thành phần phụ thuộc của hook thay đổi. Điều này có thể hữu ích để duy trì trạng thái của một thành phần khi nó được kết xuất lại ở cùng một vị trí.
Dưới đây là một ví dụ về cách sử dụng hook useMemo
để duy trì trạng thái của một thành phần:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">function</span> <span class="token function">Counter</span> <span class="token punctuation">(</span> <span class="token parameter"><span class="token punctuation">{</span> initialCount <span class="token punctuation">}</span></span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">[</span> count <span class="token punctuation">,</span> setCount <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span> <span class="token punctuation">(</span> initialCount <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> increment <span class="token operator">=</span> <span class="token function">useMemo</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 keyword">return</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setCount</span> <span class="token punctuation">(</span> count <span class="token operator">+</span> <span class="token number">1</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> count <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 punctuation">></span></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">The count is: </span><span class="token punctuation">{</span> count <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 tag"><span class="token tag"><span class="token punctuation"><</span> button</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> increment <span class="token punctuation">}</span></span> <span class="token punctuation">></span></span> <span class="token plain-text">Increment</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 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> |
Trong ví dụ này, chúng ta có một thành phần Counter
hiển thị số đếm và có một nút tăng count
khi được nhấp. Hàm increment
được tạo bằng hook useMemo
và chỉ được tính toán lại khi biến trạng thái count
thay đổi. Điều này có nghĩa là hàm increment
sẽ luôn có giá trị chính xác của count
, ngay cả khi thành phần Counter
được hiển thị lại ở cùng một vị trí trên trang.
Điều quan trọng cần lưu ý là mảng phụ thuộc của hook useMemo
phải bao gồm bất kỳ biến đạo cụ hoặc trạng thái nào mà giá trị được ghi nhớ phụ thuộc vào. Trong trường hợp này, hàm increment
phụ thuộc vào biến trạng thái count
, vì vậy nó được bao gồm trong mảng phụ thuộc.
Nếu phần phụ thuộc của hook useMemo
không được chỉ định chính xác, thì giá trị được ghi nhớ có thể được tính toán lại một cách không cần thiết, điều này có thể dẫn đến các vấn đề về hiệu suất.
Phần kết luận
Chúng ta đã thảo luận về một số khái niệm liên quan đến trạng thái và hiệu ứng trong React. Chúng tôi đã đề cập đến các chủ đề như tạo trạng thái, thiết lập trạng thái bên trong trình xử lý sự kiện, sử dụng chức năng dọn dẹp với hook useEffect, cập nhật trạng thái khi chỗ dựa thay đổi và giữ nguyên trạng thái của thành phần khi nó được kết xuất lại ở cùng một vị trí trên trang.
Việc hiểu các khái niệm này rất quan trọng để viết mã hiệu quả và hiệu quả trong React, cũng như để hiểu cách thức hoạt động của trạng thái và hiệu ứng trong khung React.
Như mọi khi, tôi hy vọng bạn thích bài viết này và học được điều gì đó mới. Xin cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo!
Nếu các bạn thích bài viết này thì hãy cho mình 1 like và subscribe để ủng hộ mình nhé. Cảm ơn bạn.