samvera-labs / ramp

Interactive, IIIF powered audio/video media player React components library. Styleguidist Docs: https://samvera-labs.github.io/ramp/
https://ramp.avalonmediasystem.org/
30 stars 5 forks source link

Investigate State Management Alternatives #605

Closed joncameron closed 1 month ago

joncameron commented 2 months ago

Description

What's the current state of the field in state management for React? Investigate and determine which we want to use moving forward as parts of Ramp are refactored. Multiple re-renders are a current paint point in Ramp.

There are multiple options for state management to explore.

Done Looks Like

Dananji commented 1 month ago

There are multiple state management solutions for React such as; Redux, Jotai, MobX, Recoil, etc. focusing on different areas of expertise and for different scales of applications. And from what I read in blogs, forums, and some documentation it seems Zustand and Recoil are the ones that provide better performance optimization when it comes to state management. And out of those 2, Recoil is a fairly new library with a steeper learning curve, suitable for larger applications which require advance state management.

The goal of the investigation was to evaluate whether we need to bring in a new library for state management or whether we could keep using the current solution with some modifications.

So, the comparison was made between Zustand and Context API (existing solution) with custom hooks (new implementation).

Option 1: Context API with Custom Hooks

Using the existing React Context for state management with additional custom hooks. Custom hooks allow us to abstract reusable logic while the Context API provides a way to share state.

Pros:

Cons:

Effort:

Option 2: Zustand

A state management library that is minimal, highly performant, scalable, and easy to use. It provides a centralized way to manage state with less boilerplate and more advanced features compared to the Context API with custom hooks.

Pros:

Cons:

Effort:

Summary

Zustand React Context API with custom hooks
Initial setup Requires more effort, as we need to strip the existing state management system and setup a new library. Setting up Zustand should be easy as it has minimal boilerplate. Requires time and effort learn a new library. Context API is already setup, but needs effort to identify code which could be broken into custom hooks and setting them up as needed
Performance Handled automatically by the library Performance can still be degraded with unnecessary re-renders, as the application grows. These need to be handled manually
Features Provides async actions, support for middleware, and persistence out of the box Highly customizable, but needs effort to implement and maintain these features. May be effort on this work would be reduced with changes in React 19?
Scalability Scales gracefully, and doesn't require extra work to make this work Could be harder to maintain custom hooks and splitting contexts as the application grows, and the code can get complex as things grow
Code quality and maintenance Code would be cleaner, readable, and easier to understand for a new developer as there's minimal customization. But, this adds one more additional dependency to manage. Code would be more complex than implementing Zustand as we add custom hooks and split contexts. But at the same time this option gives us the flexibility, as well as transparency (no magic!) in state management, and also the ability to re-use most of the state management code between components using custom hooks. And this doesn't require us to manage and maintain an external dependency as all of this is native.

[!NOTE]
There is a possibility that none of this might fix the issue we were facing with collapsing/expanding sections in StructuredNavigation component because of the nested architecture of that component. I suggest that, we explore whether there's a better way for us to populate StructuredNavigation without the nested architecture and I can explore this as a part of this ticket. And if it's a possible solution and requires more effort, I think we can create a new ticket to continue that work.

Dananji commented 1 month ago

One of the questions we needed answered with this investigation is to whether we can solve the structure re-rendering issue with fixing state management. So, I did a little bit of deep dive into the performance enhancement solutions I came across related to context API. I read more on custom hooks, and from what I understood it can be used to solve the structure re-rendering issue we had with state management. But I wasn't sure whether this will work with the nested architecture of the component. So, to explore this, I worked on a PoC. And it seems like it could be a solution for us if decide to keep working with context API state management.

elynema commented 1 month ago

We like the idea of staying the course with React and utilizing new functionality as it is added, rather than pivoting to a new library and potentially having to return in the future if the library is no longer supported or doesn't support new functionality. So stick with Context API and custom hooks. Pull out and encapsulate custom hook functionality that is reusable across components.

Ramp is using React 17. We need to update that to at least 18.3 before working on restructuring state management. React 18 has some new hooks to help with state loading and UI.

elynema commented 1 month ago

Create one more big ticket to identify code that needs to be built into custom hooks and do that work.