Can I use RxJS vs Redux/context when trying to manage and access state in different components and handler methods
Asked Answered
D

6

138

I know Redux is a better "implementation" of Flux, or better saying it's a redesign to simplify things (application state management).

I have heard a lot about reactive programming (RxJS), but I haven't dived to learn it yet.

So my question is: are there any intersection (anything in common) between this two technologies or they are complementary? ...or totally different?

Redux, along with the Reach context api, is a way to create and manage a state store which can be observed through Redux actions.

RxJS, a reactive programming language, has the ability to set and access state from different components without the overhead of Redux actions and reducers.

For the purpose of managing and accessing state where might Redux be more useful as a state store as opposed to a reactive programming paradigm?

How would you decided to use one vs the other for the purposes of managing and accessing state in various components?

Dom answered 28/12, 2015 at 16:44 Comment(0)
M
223

In short, they are very different libraries for very different purposes, but yes there are some vague similarities.

Redux is a tool for managing state throughout the application. It is usually used as an architecture for UIs. Think of it as an alternative to (half of) Angular.

RxJS is a reactive programming library. It is usually used as a tool to accomplish asynchronous tasks in JavaScript. Think of it as an alternative to Promises.


Reactive programming is a paradigm (way of working and thinking) where data changes are observed from a distance. Data is not changed from a distance.

Here is an example of changed from a distance:

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

The Model is changed from the Controller.

Here is an example of observed from a distance:

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

In the Logger, we observe the data changes that happen in Store (from a distance), and write to the console.


Redux uses the Reactive paradigm just a little bit: the Store is reactive. You do not set its content from a distance. That's why there is no store.set() in Redux. The Store observes actions from a distance, and changes itself. And the Store allows others to observe its data from a distance.

RxJS also uses the Reactive paradigm, but instead of being an architecture, it gives you basic building blocks, Observables, to accomplish this "observing from a distance" pattern.

To conclude, very different things for different purposes, but share some ideas.

Mukerji answered 28/12, 2015 at 22:42 Comment(6)
No, you shouldn't use them together. People have emulated Redux using Rx. A quick Google will find examples for you. If you want to use Rx for your reactive UI, checkout Cycle.js, Andre's framework. I've been using it lately and it is fantastic. The API has been changing a lot recently, but I believe he is finally starting to freeze parts of it.Whipsaw
according to the official redux docs, "They work great together."Cariole
They do work great together! There is a Redux middleware which gives you the opportunity to use RxJS and Observables for Redux actions. github.com/redux-observable/redux-observable Additionally I wrote a blog post about the How To: robinwieruch.de/redux-observable-rxjsSisal
The Redux paradigm helped make my Android project codebase more reactive. Our data flows coming from buttons and other fields to update a state, in conjunction with RxJava, supercharged our readability and performance. The libraries definitely do go well together, and their benefits are language-agnostic.Adorn
They work great together, but in practice Reactive can do for you what Redux would do - sync the state of your components to model, so often it doesn't make much sense to use bothHonan
People keep saying they're very different things. that's not true. They're very similar things in respect to giving data in memory for different components of your app. The difference is actually the store prior to being observed or "used." Here is a quote from the redux page itself which is the second part of that comments above. The question is: do you really need Redux if you already use Rx? Maybe not. It's not hard to re-implement Redux in Rx. Some say it's a two-liner using Rx .scan() method. It may very well be!Sextans
P
48

They are very different things.

RxJS can be used to do Reactive Programming and is a very thorough library with 250+ operators.

And Redux is as described on the github repo "Redux is a predictable state container for JavaScript apps".

Redux is just a tool to handle state in apps. But in comparison you could build a full app in just RxJS.

Hope this helps :)

Primaveria answered 28/12, 2015 at 22:36 Comment(3)
Your answer is good too @cmdv. I didn't see it when I was writing mine.Vermicide
Does Rxjs work with React native ?Collaborate
@Collaborate yes it works well with react-nativeCerecloth
J
9

Redux is a just a state management library coming with well defined standards for update operations. As far as you stick with the standards you can keep your data flow sane and easy to reason. It also brings the ability to enhance the data flow with middlewares and store enhancers.

RxJS is a toolkit for reactive programming. You can actually think of every thing happening in your app as a stream. RxJS gives a very rich tool set to manage those streams.

Where RxJS and Redux intercepts? In redux you update your state with actions and obviously these actions can be treated as streams. Using a middleware like redux-observable (you don't have to) you can implement your so called "business logic" in a reactive way. Another thing is that you can create an observable from your redux store which sometimes might be easier than using an enhancer.

Joleenjolene answered 30/6, 2019 at 5:11 Comment(0)
B
4

To put it in short:

Redux: Flux inspired Library used for State Management.

RxJS: It is another Javascript library based on the reactive programming philosophy, used to deal with "Streams" (Observables, etc.) [Read about Reactive Programming to understand the Stream concepts].

Backfield answered 16/6, 2018 at 12:54 Comment(0)
K
1

I just wanted to add some pragmatic differences from when I did Redux-inspired RxJS-code.

I mapped each action type to a Subject instance. Each stateful component will have a Subject that is then mapped into a reducer function. All reducer streams are combined with merge and then scan outputs the state. The default value is set with startWith just before the scan. I used publishReplay(1) for states, but might remove it later on.

The react pure render function will be to only place where you produce event data by sending in all the producers/Subjects.

If you have child components, you need to describe how those states are combined into yours. combineLatest might be a good starting point for that.

Notable differences in implementation:

  • No middleware, just rxjs operators. I think this is the biggest power and weakness. You can still borrow concepts, but I find it hard to get help from sister communities like redux and cycle.js since it's yet another custom solution. That's why I need to write "I" instead of "we" in this text.

  • No switch/case or strings for action types. You have a more dynamic way of separating actions.

  • rxjs can be used as a tool elsewhere, and is not contained to state management.

  • Less number of producers than action types(?). I'm not sure about this, but you can have many reactions in parent components that listen to child components. That means less imperative code, and less complexity.

  • You own the solution. No framework needed. Good and bad. You will end up writing your own framework anyhow.

  • It's much more fractal, and you can easily subscribe to changes from a sub-tree, or multiple parts of the app state tree.

    • Guess how easy it is to do epics as redux-obseravble do? Really easy.

I'm also working on much bigger benefits where the child components are described as streams. This means that we don't have to complect parent and child state in the reducers, since we can just ("just") recursively combine the states based on the component structure.

I also think about skipping react and go with snabbdom or something else until React handles reactive states better. Why should we build our state upwards just to break it down via props again? So I will try to make a version 2 of this pattern with Snabbdom.

Here's a more advanced but small snippet where the state.ts file builds the state stream. This is the ajax-form component's state which gets an object of fields (inputs) with validation rules and css styles. In this file we just use the field names (object keys) to combine all the children's states into the form state.

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
  }
}

While the code might not say much in isolation, it shows how you can build state upwards, and how you can produce dynamic events with ease. The price to pay is that you need to understand a different style of code. And I love to pay that price.

Kokaras answered 18/11, 2016 at 10:37 Comment(2)
It's a year later, I just found your answer and think it's still valid! I did something similar and agree with all of your points. But a question anyhow: Do you still think the same today, or have you moved on since?Heraldry
I need to revise the critique on switch/case and action types in Redux. I still do code the same way, but trying to work in how to get it working server-side. When it comes to React code, I've managed to do a small util that helps creating the reducers/updaters. So I'm still doing the same thing, but a bit more polished. Biggest change is that I let each leaf node subscribe to the stream on componentDidMount and unsubscribe on componentDidUnmount. I want to get a reactive service layer too that works on the frontend and backend. Making progress there.Grantley
I
0

Yes, you can and it can be simpler than Redux/Context.

Rxjs provides many more features, the key is to rely on a few of them in your project to keep it simple. Rxjs provides different types of Subjects, the one you will need is BehaviorSubject. Example:

export const mySpecificDataSubject = new BehaviorSubject<string>(null);

// get the current data anywhere in the application:
mySpecificDataSubject.getValue()

// set the data anywhere:
mySpecificDataSubject.set('new value')

// get the "global state" in any component
const [value, setValue] = useBehaviorSubject(mySpecificDataSubject)
// setValue does that globally too


// a reusable hook to facilitate the work:

const useBehaviorSubject = (subject) => {
  const [value, setValue] = useState(subject.getValue());

  const updateValue = useCallback(
    (value) => {
      subject.next(value);
    },
    [subject]
  );

  useEffect(() => {
    const subscription = subject.subscribe((v) => {
      setValue(v);
    });

    return () => subscription.unsubscribe();
  }, []);

  return [value, updateValue];
}

I also suggest using subjects for each context in its file so it's easier to maintain (just like reducers). In that way is also possible to use the store out of react components.

warning: Using more than BehaviorSubject and the available operators the learning curve can be huge for new joiners in the project.

considering only the global state management features, to get the same benefits and simplicity I would go with zustand.

Indigestion answered 14/3, 2024 at 19:30 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.