2015-06-30 22 views
7

Tôi đang viết lại một ứng dụng nhỏ để thử và hiểu rõ hơn React. Tôi đang cố gắng xác định phương pháp "chính xác"/hiệu quả nhất để chia sẻ dữ liệu "singleton" - ví dụ: người dùng đã được xác thực chính xác khi đăng nhập.Chia sẻ dữ liệu toàn cầu/singleton trong ứng dụng phản ứng

Ngay bây giờ phụ huynh "ứng dụng" thành phần có một tài sản user trong trạng thái của nó, mà tôi vượt qua các thành phần con như một chỗ dựa:

<Toolbar user={this.state.user} /> 
<RouteHandler user={this.state.user}/> 

(Tôi đang sử dụng phản ứng-router). Điều này làm việc, và trong trường hợp chỉ đọc như thế này, không phải là khủng khiếp. Tuy nhiên, thành phần mẫu đăng nhập thực tế của tôi (đó là một con đường, và sẽ là bên RouteHandler), cần một số cách để "thiết lập" các dữ liệu người dùng mới, vì vậy tôi cũng cần phải vượt qua trong một số callback:

<RouteHandler onAuthenticated={this.setUser} user={this.state.user}/> 

Không một vấn đề lớn, ngoại trừ thực tế là bây giờ phương pháp này có sẵn cho mọi "tuyến đường" được xử lý bởi RouteHandler.

Tôi đã đọc và dường như giải pháp thay thế duy nhất là hệ thống kiểu EventEmitter hoặc Dispatch.

Có cách nào tốt hơn tôi bị thiếu không? Là một hệ thống phát hiện/điều phối sự kiện có giá trị sử dụng khi thực sự chỉ có một hoặc hai sử dụng trong một ứng dụng nhỏ này?

+0

một bạn đang sử dụng thông lượng? Trong một ứng dụng Flux, trạng thái như thế này sẽ đi vào một cửa hàng (ví dụ: "SessionStore"). –

+1

bạn có thể viết một mixin để xử lý 'localStorage' và lưu người dùng dưới dạng một mục. – marcel

Trả lời

0

Đối với singleton - bạn chỉ có thể tạo mô-đun riêng cho dịch vụ người dùng và nhập mô-đun đó vào mô-đun nơi bạn xác định các thành phần cần nó.

Tùy chọn khá tương tự, nhưng mạnh mẽ hơn, là sử dụng DI container - xác định các thành phần phản ứng của bạn dưới dạng dịch vụ trong vùng chứa DI, phụ thuộc vào các dịch vụ khác như dịch vụ cho dữ liệu người dùng. Điều này sẽ phù hợp hơn với ứng dụng phổ quát (isomorphic) - bởi vì, bạn sẽ có thể dễ dàng thay thế các phụ thuộc với các triển khai cụ thể hoặc trong trường hợp bạn cần tạo các cá thể riêng biệt cho các phạm vi riêng biệt (như cho các phiên người dùng phía máy chủ). Ngoài ra nếu sử dụng cách tiếp cận này, tôi khuyên bạn nên tách riêng các thành phần phản ứng tinh khiết khỏi logic - bạn có thể tạo thành phần tinh khiết riêng biệt nhận tất cả dữ liệu và gọi lại làm đạo cụ, và hơn tạo thành phần HoC trong vùng chứa DI sẽ quấn nó và sẽ chuyển dữ liệu và cuộc gọi lại cần thiết.

Nếu bạn cần DI container - có rất nhiều, nhưng tôi sẽ khuyên bạn nên nhìn vào hộp 2 di chuyển góc, hoặc nếu bạn muốn một cái gì đó đơn giản - dưới đây tôi tham chiếu dự án của tôi, nó rất đơn giản nhưng mạnh mẽ DI lấy cảm hứng từ góc 2 DI (thật dễ dàng để kéo từ dự án đó - chỉ cần một tập tin + kiểm tra)).


Về thông báo cho các thành phần về những thay đổi và tổ chức Logic async - bạn vẫn sẽ cần một cái gì đó giống như EventEmitter để thông báo cho các thành phần về những thay đổi, và bạn sẽ cần phải viết callbacks vòng đời cho các thành phần để đăng ký/hủy đăng ký từ cập nhật ... Bạn có thể làm điều này bằng tay hoặc tạo mixin hoặc HoC để rút ngắn điều đó.

Nhưng theo quan điểm của tôi, có cách tiếp cận tốt hơn - hãy thử lập trình phản ứng và RxJS nói riêng. Nó chơi rất tốt với phản ứng.

Nếu bạn quan tâm đến các tùy chọn kết nối Rx với React - hãy xem gist https://gist.github.com/zxbodya/20c63681d45a049df3fc, cũng có thể hữu ích khi triển khai thành phần HoC với đăng ký EventEmitter được đề cập ở trên.

Tôi có một dự án được thiết kế để tạo isomorphic (phía máy chủ được hiển thị và hơn cùng một khách hàng sử dụng lại html) tiện ích con với phản ứng. Nó có DI container để vượt qua phụ thuộc, và nó sử dụng để quản lý RxJS Logic async:

https://github.com/zxbodya/reactive-widgets

0

Một cách là để đăng ký vào một Quan sát phát ra từ mô hình dữ liệu của bạn.

Router.run(routes, Handler => 
    Model.subject.subscribe(appState => 
     React.render(
      <Handler {...appState}/>, 
      document.getElementById('app') 
     ) 
    ) 
); 

... AppState là dữ liệu đến từ quan sát được (trong mô hình trường hợp này), làm cho những đạo cụ của bạn để bạn có thể cho chúng ăn để ứng dụng như dưới đây

<RouteHandler {...this.props} /> 

và bất kỳ thành phần con có thể chọn chúng với this.props

câu trả lời là phức tạp hơn mà điều này nhưng nếu bạn nhìn vào RxJS+React bạn sẽ nhận được một ví dụ làm việc đầy đủ các dữ liệu đơn giản chảy

Các vấn đề liên quan