Article thumbnail

🌟 State management with rxjs in React

10m
architecture
data flow

Intro

Let's check how state management implemented with the RxJs library works in React. We'll implement a simple state manager using reactive patterns.

Prelude

In React world, changes on UI are caused by state changing inside your components. To simplify, we can say that state is equal to UI.

Everything looks very easy if you have simple features. In more advanced ones or in a bigger application, state management can cause headaches. If you implement it in a wrong way, it can lead to huge problems with maintenance later.

Let's check how we can achieve nice and clean state management with rxjs and ContextAPI.

Yup, I know we have redux/FLUX and other stuff 👽.

1. State/logic outside component

Firstly, you need to move state management logic outside of React ecosystem. I know it may sound strange but trust me. With this approach you will have:

  • Independent testing
  • Reusability
  • Option to easily migrate to other technology
  • Easy to replace the logic

Multi-layered architecture is an investment. Of course, initially, it takes more time to implement something but later it saves a lot of your time if it's not too complicated.

Loading

Right now, we have the first layer which is responsible for the creation of store objects with public API. This API allows us to change the state and notify all subscribers.

2. Usage in React component

In React we need to use two hooks to connect our module with the functional component. With useMemo() we create only one instance of store object per component's life cycle. With useEffect() we update the state based on the signals from our module store and this triggers rerender.

Loading

This approach gives us the full power of rxjs. Right now, we can use the operator to handle side effects and other complicated logic.

3. Sharing state without ContextAPI

You can share created store inside components via simple imports statements between files. This gives you the same behavior as with redux without tons of boilerplate. As in redux you will need to reset the state if needed.

Loading

4. Usage with ContextAPI

This approach gives you full encapsulation and connection with React ecosystem. Right now, there is no need to reset the state. You determine in components where dedicated store API can be exposed in the component tree.

Loading

As you probably noticed we're exposing a dedicated hook to hide Context details.

Loading

Now, you have two options. You can implement state management with or without ContextAPI. It depends on your needs.

5. Let's create a consistent API

Of course, we can manually write this code for every feature, but it's a bit frustrating and time consuming. In addition, we can make some mistakes or provide different APIs. To avoid this problem we need abstraction.

Firstly, lets create createStore() function which allows us to create store object.

Loading

Next, we need a hook which reduces boilerplate and connects us to React ecosystem.

Loading

Lastly, a function that creates a full feature and adds ContextAPI support. This function will return the wrapper component and hook to consume provided API in the component tree.

Loading

Let's construct ContextAPI provider and hook for reading state/performing actions.

Loading

Right now you can use it in an easy way inside the component.

Loading

Full example

Summary

I hope you enjoyed this article. Now you are able to use rxjs in your projects. From my point of view, it works really well. It's lightweight and scalable, and you can customize it for your needs.

Remember, the solution which you should use depends on the project's specification.

Feel free to contact me if you have any questions/proposals. Have a nice day and good health!

I create content regularly!

I hope you found my post interesting. If so, maybe you'll take a peek at my LinkedIn, where I publish posts daily.

Comments

Add your honest opinion about this article and help us improve the content.

created: 13-06-2022
updated: 02-07-2022