markdown Quảnlýstatetrong React&React Nativekhôngsửdụng州管理库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Quảnlýstatetrong React&React Nativekhôngsửdụng州管理库相关的知识,希望对你有一定的参考价值。

Đối với những bạn đã biết và sử dụng React & React Native thì việc dùng kèm 1 thư viện để quản lý state như Redux là điều rất phổ biến. Mình cũng sử dụng React được một thời gian tuy nhiên thời gian đầu mình hay sử dụng theo hướng thuần - không sử dụng thư viện riêng biệt để quản lý state (lấy Redux làm đại diện). Trong bài viết này mình sẽ chia sẻ và trao đổi một số tips khi làm việc với React & React Native theo hướng thuần.

Lưu ý: 
- Bài viết chỉ đơn giản là chia sẻ và trao đổi, không khuyến khích các bạn bỏ Redux, do vậy hãy giữ tư tưởng mở.
- Để hiểu rõ bài viết thì nên có kiến thức về React, đối với những bạn mới tiếp xúc với React / React Native nếu gặp khó khăn trong việc học Redux (phải học trước một đống thứ như React, JSX, Babel, Webpack, Native Component & Native Module dẫn đến ngợp), thì hy vọng bài viết này sẽ cung cấp cho các bạn 1 cái gì đó để thoải mái hơn và vững vàng hơn trước khi học những cái mới.

## Nhắc lại vấn đề quản lý state của React

- Luồng dữ liệu `pass data down, pass event up`. làm cho phải truyền data và function qua props khá nhiều, khi app phức tạp dần lên thì rất khó quản lý. (Vấn đề quản lý dữ liệu giữ component cha - con )
- Truyền qua props thì các component không cùng cây thư mục rất khó giao tiếp (Vấn đề giao tiếp giữa các component)
- Vấn đề đồng bộ dữ liệu giữa các component khi 1 thông tin chung thay đổi.

Giải pháp? Redux ? Redux giải quyết các vấn đề trên khá OK, tuy nhiên nó kèm theo một đống thứ khác nữa khiến việc học và vận dụng trở nên khó khăn. Bài viết sẽ cung cấp 2 hướng tiếp cận và 1 loạt các tool sử dụng trong các trường hợp.

## Hướng tiếp cận 1: Global Store - Single Source of Truth
Global Store là chính tư tưởng của Redux, tuy nhiên nó có thể được thực hiện chỉ cần sử dụng React. 
### 1. Context
`context` là một phần ít được đề cập trong React. Sử dụng `context` thì có thể giao tiếp giữa component cha với component con mà không cần pass qua các component ở giữa. Thông tin về `context` các bạn có thể đọc thêm ở [đây](https://reactjs.org/docs/context.html). Luồng làm việc với `context` sẽ như sau:

1. Khai báo context ở Component to nhất (Tạm gọi là Root )
2. Tạo 1 method ở Root có thể get/set `state`.
3. Truyền method đó qua `context`
4. Khai báo nhận `context` ở các Component con (Tạm gọi là Child). Child chỉ việc sử dụng method này để get/set `state` của Root. 
5. Mọi thông tin cần thiết đều lưu vào `state` của Root. Khi có thay đổi thì Root sẽ render lại dẫn đến UI được cập nhật một cách tự động.

Tham khảo Gist: https://gist.github.com/lequanghuylc/2d9c0ff12c6ac64557c0acb4a0987ff1

__Vấn đề với việc sử dụng `context`__: Bản thân Facebook cũng không khuyến khích sử dụng context, vì nó có thể thay đổi trong tương lai, cũng như nếu sử dụng không chuẩn sẽ rất rối. Tuy nhiên chúng ta hãy lướt qua các thư viện nổi tiếng:

- [`react-redux`](https://github.com/reactjs/react-redux/search?utf8=%E2%9C%93&q=context&type=) sử dụng `context` (không đáng kể)
- [`react-router`](https://github.com/ReactTraining/react-router/search?utf8=%E2%9C%93&q=context&type=) sử dụng `context`
- [`react-navigation`](https://github.com/react-navigation/react-navigation/search?utf8=%E2%9C%93&q=context&type=) sử dụng `context`
- Nhiều [thư viện về UI](https://github.com/mui-org/material-ui/search?utf8=%E2%9C%93&q=getChildContext&type=) sử dụng `context`

Mặc dù không nhiều tuy nhiên `context` vẫn được sử dụng. Vấn đề là cách sử dụng thế nào mà thôi. Mặt khác gói trong Root và Child thì sẽ không làm việc trực tiếp với `context` (_this.store_), nếu `context` bị loại bỏ ở React trong các phiên bản sau, chúng ta hoàn toàn có thể cập nhật lại 2 file Child và Root (bằng giải pháp tiếp dưới đây) là xong.
### 2. Export method setState
Giải pháp này hoàn toàn có thể thay thế `context`, ngoài ra còn vượt trội hơn khá nhiều khi có thể truy cập được ngoài phạm vi React, giữa các React Application với nhau (trường hợp website hỗn hợp React và các cách xây dựng UI khác).
Luồng làm việc với `export method setState` sẽ như sau:
1. Tạo 1 BaseComponent
2. Thiết lập biến `static` cho `BaseComponent`
3. Trong `componentWillMount`, gán biến `static` đó vào một function mới tạo để có thể get/set state
4. Viết lại biến `static` để có thể dùng với nhiều instance. (Có thể quản lý thông qua id)
5. Khi tạo các component thì extends từ `BaseComponent`, sau đó có thể import và gọi trực tiếp biến `static` để get/set state cho component (dĩ nhiên là component đó phải được mount vào rồi)

Bằng với cách này, chúng ta có thể quản lý mọi component ở bất cứ đâu. Nếu theo hướng Global Store, thì chỉ cần quản lý component Root là đủ. 

Tham khảo gist: https://gist.github.com/lequanghuylc/128ad8d8822d00c632a26e2737a75b81

Example app về phần này mình đang hoàn thiện và sẽ cập nhật sau.
## Hướng tiếp cận 2: Quản lý dữ liệu trong phạm vi service

`service` đơn giản là cách gọi một hoạt động được thực hiện không liên quan đến UI (headless) và đảm nhận một công việc gì đó, nôm na là sẽ viết riêng phần xử lý logic của app ra bên ngoài và trả dữ liệu cho UI để hiển thị. 

Luồng hoạt động của service:

1. Không xử lý logic trong Component
2. Tạo một `service module` có thể chạy độc lập, headless. `service` dùng để làm tính năng cho app (ví dụ như wrapper của server API, socket, local DB, thực hiện một số function native).
3. Bên component lấy kết quả từ API trả về để cập nhật UI
4. Viết `event listener` cho `service`, để cập nhật dữ liệu ngay cho UI

1 ví dụ khá tiêu biểu cho việc sử dụng `service` là [`firebase`](https://www.npmjs.com/package/firebase). Như dùng `firebase` thì login xong nó cũng không trả về token j cho mình, chỉ biết là đã login, khi nào hoạt động gì cũng sử dụng qua function của nó. Tất cả những dữ liệu đều được gói gọn bên trong và chỉ trả về ra bên ngoài những gì cần thiết. Khi firebase database có dữ liệu thay đổi, thì nó cũng cung cấp 1 vài hàm để xử lý dữ liệu mới kịp thời.

Một ví dụ về cách cấu tạo 1 service, sử dụng `class` và `state` để quen thuộc với React

```
class ServiceA {
	constructor() {
      this.syncData();
   	}

	state = {}; 
    // lưu 1 state trực tiếp bằng cách this.state.something = "something"

	syncData = () => {
       // sync data với local khi mở lại app nếu cần
    }

	login = (id, pass) => {
      // call api or something
    }

	logout = () => {
      
    }

	onLoggedOut = ( callback ) => {
      // listener dùng để chạy callback khi đã logout
    }
}

// export với new để sử dụng singleton
export default new ServiceA();
```

Ngoài việc dùng `event listener` trong `service`, bạn có thể sử dụng trực tiếp để giao tiếp giữa các component với nhau (VD: Chuyển modal alert từ dạng component sang dạng function). Tham khảo [react-native-event-listeners](https://github.com/meinto/react-native-event-listeners) và [js-events-listener](https://github.com/lequanghuylc/js-events-listener)

## Tạm kết lại
Bài viết mới dừng lại ở lý thuyết, mình sẽ cập nhật example code và giải thích sâu hơn sau nếu được. Tuy nhiên cũng khá rõ ràng để có thể suy nghĩ và xem xét rồi. 

Vậy so với __Redux__ thì sao?

Như đã nói ở trước Redux ngoài việc giải quyết các vấn đề hay gặp của React thì còn một số thứ khác nữa. Nó đề cập nhiều đến các vấn đề như architecture (từ `Flux` cho đến `Redux`), các khái niệm mới khi  implement (`action` & `reducer`), và ecosystem để dev theo `the Redux way`. So với bài viết thì chỉ đơn giản cung cấp cho bạn 1 vài công cụ để có thể làm được nhiều thứ hơn với React thuần. Bạn có thể sử dụng tự do theo ý thích. (Thực tế sử dụng `Redux` không tốt cũng rất dễ rối do số lượng `action` và `reducer` ngày càng tăng. Điều quan trọng vẫn là cách tổ chức của dev).

Hãy thử tạm quên `Redux` đi và suy nghĩ về các công cụ trên :) 

以上是关于markdown Quảnlýstatetrong React&React Nativekhôngsửdụng州管理库的主要内容,如果未能解决你的问题,请参考以下文章

markdown QuéesyparaquésirveSelenium IDE

php TấtcảcácthamsốtrongWP_Query

php 修理mộtsốlỗ他cơbảnk息triểnkhaiựánlaravellênhost

php 修理mộtsốlỗ他cơbảnk息triểnkhaiựánlaravellênhost

统计输入的行数,单词数和字符数

如何防止这样的 unicode 字符Ả̴̢̦̙̬̲̯̖̲̟̟̬̲̻̣̩͕͍̦͍̮̠̤͇̿́̾͋́̾̎̔̐̓̾̐̉͒̅͛̈́̀̇͋͋̔̕͘͝͝͝ 在我的网站上,为啥它们存在? [复制]