Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can redux be seen as a pub/sub or observer pattern?

I'm just trying to get my head around react.js, that being said, I just finished a few tutorials on the web.

I am completely new to redux, which is part of some video tutorials I watched. The more I dive into it, the less it makes sense to me in terms of redux replacing the initial idea of react.js. In react a component has its own state which can be passed down via props, to keep the workflow from top to bottom.

With redux we now try to make the whole application state global and we have to define actions to manipulate that (global) state, so what are these actions other than a "normal" javascript pub/sub or observer pattern? Or maybe I am getting it wrong? - Clarification would be highly appreciated.

like image 766
thooyork Avatar asked Oct 11 '16 12:10

thooyork


People also ask

Is Redux an observer pattern?

As you can see, Redux is an implementation of the Observer pattern. The beauty of this pattern is that an observer is observing only the relevant slice of the app state instead of the entire app state. The observer is only updated when necessary.

Is Redux pub sub?

Yes in my view it's like a pub/sub with a convention. To illustrate how passing down props can be a pain, here's an example. Let's say you have a component that displays the current logged in user.

What design pattern is Redux?

At its core, Redux is really a fairly simple design pattern: all your "write" logic goes into a single function, and the only way to run that logic is to give Redux a plain object that describes something that has happened.

Is Pub sub an observer pattern?

In the observer pattern, the source of data itself (the Subject) knows who all are its observers. So, there is no intermediate broker between Subject and Observers. Whereas in pub-sub, the publishers and subscribers are loosely coupled, they are unaware of even the existence of each other.


2 Answers

Redux is not supposed to "replace the initial idea of react.js", think of it more like a library to managed shared state between components and to coordinate state mutations. Redux does use a pub/sub pattern indeed, see the store methods here: http://redux.js.org/docs/api/Store.html#store-methods You'll find a subscribe method that is used by components to subscribe to changes in the state tree. Normally you don't use store.subscribe directly, as the Redux-React bindings (Redux connect basically) do that for you. You can check out the actual implementation here, it's not that complicated to follow (in fact to me that's the main benefit of Redux over other Flux implementations): https://github.com/reduxjs/react-redux/blob/4.x/src/components/connect.js#L199

That code, apart from subscribing to the changes emitted by the store, also perform some optimisations, such as passing new props to the component (and hence triggering a re-render) only when that's really needed.

Consider also that it's perfectly fine to keep using the components internal state together with Redux. You can use the internal state to store state you don't need/want to share with other components.

You see the need of something like Redux when you have a more complicated application, with top-level components that need to talk to each other (actions) and somehow share some state.

Actions in Redux are by default just POJO (plain old javascript objects), you can think of them as "events" that you often dispatch in response to user-triggered actions (e.g. user clicked on a button), but you're not limited to that, you can dispatch an action from wherever you want. The Redux store listens for these actions and calls the reducers (pure functions) passing the action object you dispatched.

Reducers intercepts all the dispatched actions and they can return a new, updated state for the slice of state they manage.

In this sense, a reducer is a function that processes the actions and updates the state as needed.

In turn, when a reducer updates the state by returning a new copy of the state, connected components (subscribed to the changes in the state) will be passed new props and will re-render to reflect the changes.

Sometimes, dispatching just plain js objects is not enough and you need more control. That becomes clear when you need to perform more complicated logic, for instance when you need to update a counter in the state based on the response from an AJAX call.

With redux-thunk you can dispatch functions as opposed to just plain objects. By dispatching a function, you're effectively implementing the inversion of control pattern in a very simple way. You action becomes a "recipe" described by the function, and not just a simple statement, as with a POJO action.

Why just POJOs supported "out of the box", for actions, why isn't there a base Action class or something? Mainly because there's no need for that. A simple object (considered as a bag for values basically) with a type property is all you really need, it's basically the simplest possible interface. You can consider this to be programming against an interface (the action) instead of an implementation.

Why a global state is better, instead of each component managing its own state? Mainly because managing the state is actually the hardest part of a non-trivial js app. By using Redux, you extract all that logic from the UI layer, making it easier to test. In fact, you should ideally be able test all the real "business logic" of a Redux app without even rendering a single component.

Components become "dumber" and "purer" as they just render what they are told to do. "Purer" here means that because they don't hold any state, what you see rendered just depends on the inputs (read "props") at any given point in time, and not by any history, hence "stateless".

Having the state as a single, json serialisable object also makes it easy to debug, to snapshot it and send/restore from a server or local storage.

like image 184
fabio.sussetto Avatar answered Oct 21 '22 11:10

fabio.sussetto


Can't upvote Fabios answer twice and the comments section is to small:

Yes in my view it's like a pub/sub with a convention.

To illustrate how passing down props can be a pain, here's an example.

Let's say you have a component that displays the current logged in user. Your components hierarchy is like a huge tree. Now if you would display that component on a branch starting at the root, and in another branch also starting at the root, each deep deep down in the hierarchy, you would have to pass the user infos from the root component to the leaf nodes on 2 different paths, polluting the props of every components in the way (which aren't related at all to user's infos, but now they need to know).

like image 12
Mike Gleason jr Couturier Avatar answered Oct 21 '22 10:10

Mike Gleason jr Couturier