Redux & RxJS, có điểm tương đồng nào không?


113

Tôi biết Redux là một "triển khai" tốt hơn của Flux, hay nói tốt hơn đó là một thiết kế lại để đơn giản hóa mọi thứ (quản lý trạng thái ứng dụng).

Tôi đã nghe rất nhiều về lập trình phản ứng (RxJS), nhưng tôi vẫn chưa tìm hiểu nó.

Vì vậy, câu hỏi của tôi là: có bất kỳ điểm giao nhau nào (điểm chung) giữa hai công nghệ này hay chúng bổ sung cho nhau? ... hay hoàn toàn khác?

Câu trả lời:


185

Nói tóm lại, chúng là những thư viện rất khác nhau cho những mục đích rất khác nhau, nhưng có một số điểm tương đồng mơ hồ.

Redux là một công cụ để quản lý trạng thái trong toàn bộ ứng dụng. Nó thường được sử dụng làm kiến ​​trúc cho giao diện người dùng. Hãy coi nó như một sự thay thế cho (một nửa của) Angular.

RxJS là một thư viện lập trình phản ứng. Nó thường được sử dụng như một công cụ để thực hiện các tác vụ không đồng bộ trong JavaScript. Hãy coi nó như một sự thay thế cho Lời hứa.


Lập trình phản ứng là một mô hình (cách làm việc và suy nghĩ) nơi các thay đổi dữ liệu được quan sát từ xa . Dữ liệu không bị thay đổi từ xa .

Đây là một ví dụ về thay đổi từ một khoảng cách :

// In the controller.js file
model.set('name', 'George');

Các mẫu được thay đổi từ Controller.

Đây là một ví dụ về quan sát từ xa :

// logger.js
store.subscribe(function (data) {
    console.log(data);
});

Trong Logger, chúng tôi quan sát các thay đổi dữ liệu xảy ra trong Store (từ xa) và ghi vào bảng điều khiển.


Redux chỉ sử dụng mô hình Reactive một chút: Store là phản ứng. Bạn không đặt nội dung của nó từ xa. Đó là lý do tại sao không có store.set()trong Redux. Cửa hàng quan sát các hành động từ xa và tự thay đổi. Và Cửa hàng cho phép người khác quan sát dữ liệu của mình từ xa.

RxJS cũng sử dụng mô hình Reactive, nhưng thay vì là một kiến ​​trúc, nó cung cấp cho bạn các khối xây dựng cơ bản, Observables , để thực hiện mô hình "quan sát từ xa" này.

Để kết luận, những điều rất khác nhau cho các mục đích khác nhau, nhưng hãy chia sẻ một số ý tưởng.


4
Không, bạn không nên sử dụng chúng cùng nhau. Mọi người đã mô phỏng Redux bằng Rx. Google sẽ nhanh chóng tìm thấy các ví dụ cho bạn. Nếu bạn muốn sử dụng Rx cho giao diện người dùng phản ứng của mình, hãy xem Cycle.js, khung công tác của Andre. Tôi đã sử dụng nó gần đây và nó thật tuyệt vời. Gần đây API đã thay đổi rất nhiều, nhưng tôi tin rằng cuối cùng anh ấy cũng bắt đầu đóng băng các phần của nó.
Joel Dentici

17
theo tài liệu redux chính thức , "Chúng hoạt động tuyệt vời cùng nhau."
galki

12
Họ làm việc rất tốt với nhau! Có một phần mềm trung gian Redux cho bạn cơ hội sử dụng RxJS và Observables cho các hành động Redux. github.com/redux-observable/redux-observable Thêm vào đó, tôi đã viết một bài đăng blog về Làm thế nào để: robinwieruch.de/redux-observable-rxjs
Robin Wieruch

1
Mô hình Redux đã giúp làm cho cơ sở mã dự án Android của tôi phản ứng nhanh hơn. Các luồng dữ liệu của chúng tôi đến từ các nút và các trường khác để cập nhật trạng thái, cùng với RxJava, đã tăng cường khả năng đọc và hiệu suất của chúng tôi. Các thư viện chắc chắn hoạt động tốt với nhau và lợi ích của chúng là ngôn ngữ bất khả tri.
Kenny Worden

Họ làm việc cùng nhau rất tốt, nhưng trong thực tế phản ứng có thể làm cho bạn thấy những gì Redux sẽ làm gì - đồng bộ trạng thái của các thành phần của bạn để mô hình, vì vậy thường nó không có ý nghĩa nhiều để sử dụng cả hai
Filip Sobczak

32

Chúng là những thứ rất khác nhau.

RxJS có thể được sử dụng để lập trình phản ứng và là một thư viện rất kỹ lưỡng với hơn 250 toán tử.

Và Redux được mô tả trên github repo "Redux là một vùng chứa trạng thái có thể đoán trước cho các ứng dụng JavaScript".

Redux chỉ là một công cụ để xử lý trạng thái trong ứng dụng. Nhưng so sánh, bạn có thể xây dựng một ứng dụng đầy đủ chỉ trong RxJS.

Hi vọng điêu nay co ich :)


3
Câu trả lời của bạn cũng tốt @cmdv. Tôi đã không nhìn thấy nó khi tôi đang viết của tôi.
André Staltz,

4

Redux chỉ là một thư viện quản lý nhà nước với các tiêu chuẩn được xác định rõ ràng cho các hoạt động cập nhật. Miễn là bạn tuân thủ các tiêu chuẩn, bạn có thể giữ cho luồng dữ liệu của mình ổn định và dễ dàng suy luận. Nó cũng mang lại khả năng nâng cao luồng dữ liệu với phần mềm trung gian và phần mềm nâng cao lưu trữ.

RxJS là một bộ công cụ để lập trình phản ứng. Bạn thực sự có thể coi mọi thứ diễn ra trong ứng dụng của mình dưới dạng một luồng. RxJS cung cấp một bộ công cụ rất phong phú để quản lý các luồng đó.

RxJS và Redux chặn ở đâu? Trong redux, bạn cập nhật trạng thái của mình bằng các hành động và rõ ràng những hành động này có thể được coi là luồng. Sử dụng phần mềm trung gian như redux-Observable (bạn không cần phải làm như vậy), bạn có thể triển khai cái gọi là "logic nghiệp vụ" của mình theo cách phản ứng. Một điều khác là bạn có thể tạo một tệp có thể quan sát được từ cửa hàng redux của mình, điều này đôi khi có thể dễ dàng hơn so với việc sử dụng một trình tăng cường.


2

Nói một cách ngắn gọn:

Redux: Thư viện lấy cảm hứng từ Flux được sử dụng cho Quản lý Nhà nước .

RxJS: Nó là một thư viện Javascript khác dựa trên triết lý lập trình phản ứng, được sử dụng để xử lý "Luồng" (Observables, v.v.) [Đọc về Lập trình phản ứng để hiểu khái niệm Luồng].


1

Tôi chỉ muốn thêm một số khác biệt thực dụng so với khi tôi làm mã RxJS lấy cảm hứng từ Redux.

Tôi đã ánh xạ từng loại hành động vào một đối tượng Chủ đề. Mỗi thành phần trạng thái sẽ có một Chủ đề sau đó được ánh xạ vào một hàm giảm thiểu. Tất cả các luồng giảm tốc được kết hợp với mergevà sau đó scanxuất ra trạng thái. Giá trị mặc định được đặt startWithngay trước scan. Tôi đã sử dụng publishReplay(1)cho các tiểu bang, nhưng có thể xóa nó sau này.

Chức năng kết xuất thuần túy phản ứng sẽ chỉ ở nơi bạn tạo ra dữ liệu sự kiện bằng cách gửi tất cả các nhà sản xuất / Chủ thể.

Nếu bạn có các thành phần con, bạn cần mô tả cách các trạng thái đó được kết hợp thành của bạn. combineLatestcó thể là một điểm khởi đầu tốt cho điều đó.

Sự khác biệt đáng chú ý trong việc triển khai:

  • Không có phần mềm trung gian, chỉ có các toán tử rxjs. Tôi nghĩ đây là sức mạnh và điểm yếu lớn nhất. Bạn vẫn có thể mượn các khái niệm, nhưng tôi thấy khó nhận được sự trợ giúp từ các cộng đồng chị em như redux và cycle.js vì đây là một giải pháp tùy chỉnh khác. Đó là lý do tại sao tôi cần viết "I" thay vì "we" trong văn bản này.

  • Không có công tắc / trường hợp hoặc chuỗi cho các loại hành động. Bạn có một cách năng động hơn để tách các hành động.

  • rxjs có thể được sử dụng như một công cụ ở nơi khác và không bị quản lý nhà nước.

  • Số lượng nhà sản xuất ít hơn các loại hành động (?). Tôi không chắc về điều này, nhưng bạn có thể có nhiều phản ứng trong các thành phần cha lắng nghe các thành phần con. Điều đó có nghĩa là mã ít bắt buộc hơn và ít phức tạp hơn.

  • Bạn sở hữu giải pháp. Không cần khuôn khổ. Tốt và xấu. Dù sao đi nữa, bạn cũng sẽ viết ra khuôn khổ của riêng mình.

  • Nó phức tạp hơn nhiều và bạn có thể dễ dàng đăng ký các thay đổi từ một cây con hoặc nhiều phần của cây trạng thái ứng dụng.

    • Đoán xem sử thi dễ dàng như redux-obseravble làm như thế nào? Thật sự dễ dàng.

Tôi cũng đang nỗ lực vì những lợi ích lớn hơn nhiều khi các thành phần con được mô tả là các luồng. Điều này có nghĩa là chúng ta không phải tổng hợp trạng thái cha và con trong bộ giảm, vì chúng ta có thể ("just") kết hợp đệ quy các trạng thái dựa trên cấu trúc thành phần.

Tôi cũng nghĩ về việc bỏ qua phản ứng và sử dụng snabbdom hoặc thứ gì đó khác cho đến khi React xử lý các trạng thái phản ứng tốt hơn. Tại sao chúng ta nên xây dựng trạng thái của mình trở lên chỉ để phá vỡ nó thông qua đạo cụ một lần nữa? Vì vậy, tôi sẽ cố gắng tạo phiên bản 2 của mẫu này với Snabbdom.

Đây là một đoạn mã nhỏ nhưng nâng cao hơn trong đó tệp state.ts tạo luồng trạng thái. Đây là trạng thái của thành phần ajax-form nhận một đối tượng của các trường (đầu vào) với các quy tắc xác thực và kiểu css. Trong tệp này, chúng tôi chỉ sử dụng tên trường (khóa đối tượng) để kết hợp tất cả các trạng thái con thành trạng thái biểu mẫu.

export default function create({
  Observable,
  ajaxInputs
}) {
  const fieldStreams = Object.keys(ajaxInputs)
  .map(function onMap(fieldName) {
    return ajaxInputs[fieldName].state.stream
    .map(function onMap(stateData) {
      return {stateData, fieldName}
    })
  })

  const stateStream = Observable.combineLatest(...fieldStreams)
  .map(function onMap(fieldStreamDataArray) {
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData
    return acc
  }, {})
  })

  return {
    stream: stateStream
  }
}

Mặc dù mã có thể không nói lên nhiều điều riêng biệt, nhưng nó cho thấy cách bạn có thể xây dựng trạng thái trở lên và cách bạn có thể tạo ra các sự kiện động một cách dễ dàng. Cái giá phải trả là bạn cần phải hiểu một kiểu mã khác. Và tôi thích trả giá đó.


Phải một năm sau, tôi mới tìm thấy câu trả lời của bạn và nghĩ rằng nó vẫn còn giá trị! Tôi đã làm một cái gì đó tương tự và đồng ý với tất cả các điểm của bạn. Nhưng dù sao đi nữa, một câu hỏi: Bạn vẫn nghĩ như vậy ngày hôm nay, hay bạn đã tiếp tục?
Xceno

1
Tôi cần sửa đổi phê bình về chuyển đổi / trường hợp và các loại hành động trong Redux. Tôi vẫn viết mã theo cách tương tự, nhưng đang cố gắng tìm cách làm cho nó hoạt động ở phía máy chủ. Khi nói đến mã React, tôi đã cố gắng thực hiện một công dụng nhỏ giúp tạo các trình giảm / cập nhật. Vì vậy, tôi vẫn làm điều tương tự, nhưng bóng bẩy hơn một chút. Thay đổi lớn nhất là tôi cho phép từng nút lá đăng ký luồng trên componentDidMount và hủy đăng ký trên componentDidUnmount. Tôi cũng muốn nhận được một lớp dịch vụ phản ứng hoạt động trên giao diện người dùng và phụ trợ. Đang tiến bộ ở đó.
Marcus Rådell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.