You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cách redux hoạt động thì tụi mình đều biết cả rồi, khi update state, thì component (function) nào subscribe thông qua useSelector() thì nó sẽ được chạy lại (re-render, re-execute). Cho nên, khi viết hook thì nên chú ý tới một điều này nữa. Giả sử bây giờ có trường hợp như này đi.
Component A và Component B, đều sử dụng redux để cập nhật dữ liệu thông qua useData. Cho nên khi A update state thì B sẽ render lại và bởi vì A và B đều subscribe vào state của redux, cho nên cả thằng A cũng sẽ render lại luôn. Ok, mọi thứ ổn nếu như component A cũng dùng state. Tuy nhiên nếu như A không dùng state thì sao?
(1): A và B đều subscribe data state.
(2): A sẽ update data thông qua updateData(newData).
(3): Reducer sẽ xử lý state, cập nhật state mới.
(4): Update lại state, component A và B sẽ được render lại.
Tiếp tục giả sử một trường hợp khác đi, trường hợp thực tế, khi Explore load được 5 dữ liệu của places, thì t sẽ dùng redux để lưu lại thông tin của place đó để có thể load trước khi vào place details và chờ các dữ liệu khác được trả về. Thì lúc này, các HorizontalPlaceCard sẽ bị render lại, bởi vì t đã subscribe state của redux trong mỗi component đó. Nếu như có 100 cái HorizontalPlaceCard thì sao? Rất tiếc cho cái vấn đề này là t đã có giải pháp.
Solutions
Trong mỗi Redux sẽ có 2 phần chính đó là state và action. State sẽ là thằng luôn được cập nhật khi được thay đổi và thằng action thì không, nó là các hàm tĩnh, không thay đổi theo thời gian. Vì action được thiết kế theo hướng dấu state, cho nên sẽ khá dễ để tách phần state và action ra làm hai. Từ useData thành useDataState và useDataActions. Lúc này thì chỉ có thằng nào dùng useDataState thì mới subscribe vào state của Redux, có nghĩa là chỉ có thằng đó mới render lại thôi. useDataState
Và giờ A chỉ dùng useDataActions để update state và B dùng useDataState để dùng data state. Nên lúc này, chỉ có B render lại thôi, A vẫn thế.
(1): A dùng useDataActions, B dùng useDataState (subscribe vào redux state).
(2): A sẽ update data thông qua updateData(newData).
(3): Reducer sẽ xử lý state, cập nhật state mới.
(4): Update lại state, chỉ có component B sẽ được render lại. A sẽ vẫn thế.
Giờ thì ví dụ thực luôn nè. Ở đây t có 3 hook usePlaceDetailsActions, usePlaceDetailsState và usePlaceDetails để test. usePlaceDetailsActions
Note
Cách redux hoạt động thì tụi mình đều biết cả rồi, khi update state, thì component (function) nào subscribe thông qua useSelector() thì nó sẽ được chạy lại (re-render, re-execute). Cho nên, khi viết hook thì nên chú ý tới một điều này nữa. Giả sử bây giờ có trường hợp như này đi.
Problems
Có một hook như sau
Component A và Component B, đều sử dụng redux để cập nhật dữ liệu thông qua
![image](https://user-images.githubusercontent.com/86825061/235877061-bab6c1b2-c0e9-41ad-842e-733aa36a1594.png)
useData
. Cho nên khi A update state thì B sẽ render lại và bởi vì A và B đều subscribe vào state của redux, cho nên cả thằng A cũng sẽ render lại luôn. Ok, mọi thứ ổn nếu như component A cũng dùng state. Tuy nhiên nếu như A không dùng state thì sao?(1): A và B đều subscribe
data
state.(2): A sẽ update
data
thông quaupdateData(newData)
.(3): Reducer sẽ xử lý state, cập nhật state mới.
(4): Update lại state, component A và B sẽ được render lại.
Tiếp tục giả sử một trường hợp khác đi, trường hợp thực tế, khi Explore load được 5 dữ liệu của places, thì t sẽ dùng redux để lưu lại thông tin của place đó để có thể load trước khi vào place details và chờ các dữ liệu khác được trả về. Thì lúc này, các
HorizontalPlaceCard
sẽ bị render lại, bởi vì t đã subscribe state của redux trong mỗi component đó. Nếu như có 100 cáiHorizontalPlaceCard
thì sao? Rất tiếc cho cái vấn đề này là t đã có giải pháp.Solutions
Trong mỗi Redux sẽ có 2 phần chính đó là state và action. State sẽ là thằng luôn được cập nhật khi được thay đổi và thằng action thì không, nó là các hàm tĩnh, không thay đổi theo thời gian. Vì action được thiết kế theo hướng dấu state, cho nên sẽ khá dễ để tách phần state và action ra làm hai. Từ
useData
thànhuseDataState
vàuseDataActions
. Lúc này thì chỉ có thằng nào dùnguseDataState
thì mới subscribe vào state của Redux, có nghĩa là chỉ có thằng đó mới render lại thôi.useDataState
useDataActions
Và giờ A chỉ dùng
![image](https://user-images.githubusercontent.com/86825061/235879892-95525e89-95e2-4578-be36-bcd94498ca56.png)
useDataActions
để update state và B dùnguseDataState
để dùngdata
state. Nên lúc này, chỉ có B render lại thôi, A vẫn thế.(1): A dùng
useDataActions
, B dùnguseDataState
(subscribe vào redux state).(2): A sẽ update
data
thông quaupdateData(newData)
.(3): Reducer sẽ xử lý state, cập nhật state mới.
(4): Update lại state, chỉ có component B sẽ được render lại. A sẽ vẫn thế.
Giờ thì ví dụ thực luôn nè. Ở đây t có 3 hook
usePlaceDetailsActions
,usePlaceDetailsState
vàusePlaceDetails
để test.usePlaceDetailsActions
usePlaceDetailsState
và
usePlaceDetails
Đầu tiên là dùng
![image](https://user-images.githubusercontent.com/86825061/235880958-6cd302b2-9528-40cf-839d-e4303f1843b2.png)
usePlaceDetails
, và log trongHorizontalPlaceCard
Tiếp trong
![image](https://user-images.githubusercontent.com/86825061/235881229-3f6acc5b-2c31-463c-b2b6-6a4b2c6ba540.png)
PlaceDetailScreen
dùng tiếp hookusePlaceDetails
hoặcusePlaceDetailsState
cũng được, và log thêm ở đây nữa.Giờ thì xem logs
![image](https://user-images.githubusercontent.com/86825061/235881613-25bc907f-8ee0-4eb0-bf7e-199590f65f59.png)
Thấy không,
HorizontalPlaceDetails
sẽ render lại.Giờ thì tách riêng ra,
![image](https://user-images.githubusercontent.com/86825061/235881826-1dd56ae5-09f4-49c2-8517-e549eecb2a02.png)
HorizontalPlaceCard
dùngusePlaceDetailsActions
, cònPlaceDetailScreen
dùngusePlaceDetailsState
Trong
HorizontalPlaceCard
Trong
![image](https://user-images.githubusercontent.com/86825061/235882107-5e6222ff-73c1-471b-a134-1c83d356e492.png)
PlaceDetailScreen
Giờ thì xem logs
![image](https://user-images.githubusercontent.com/86825061/235882366-63e184f7-9f98-4501-b0d2-17e061e18cfe.png)
Giờ thì
HorizontalPlaceCard
không re-rendẻ lại nữa. Ok thì cái này tới đây thôi. Ae lưu ý nhá.The text was updated successfully, but these errors were encountered: