Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] State management #125

Open
ankushdharkar opened this issue Jul 8, 2022 · 15 comments
Open

[RFC] State management #125

ankushdharkar opened this issue Jul 8, 2022 · 15 comments
Assignees

Comments

@ankushdharkar
Copy link
Contributor

No description provided.

@shreya-mishra
Copy link
Contributor

@sakshambhatt assigned to you!

@sakshambhatt
Copy link
Contributor

I am half way done with the RFC. Do we have a wiki page or notion where I can put it?

@shreya-mishra
Copy link
Contributor

I am half way done with the RFC. Do we have a wiki page or notion where I can put it?

put here itself

@sakshambhatt
Copy link
Contributor

sakshambhatt commented Jul 13, 2022

RFC no: 1 Start Date: 13th July 2022

State management in RDS RN mobile app

Table of contents

  • List of approvers
  • Abstract (what is this about?)
  • Proposed solutions
  • UI & UX
  • Architecture changes
  • Library dependencies
  • Security concerns
  • Testing & rollout

List of approvers:

  1. Ankush Dharkar
  2. Shreya Mishra

Abstract (what is this about?):

About managing all state effectively in the React Native app, in such a manner that performance and DX are good without it needing to be over-engineered.
What is state?
Data that can mutate over time and needs to be stored in app. There are two kinds of state, server cache (data being stored in DB but also being stored in UI for better UX) and UI state (data which is stored and used only in the UI, theme, isLoading, isConfirmModalOpen, etc.).

Proposed solutions:

Argument 1:

  1. No need for external state management. Memoized useContext + React-Query for the win!
    reference: Kent c Dodds blog
  2. UI state problem? Lift State up -> Component composition -> Context (Don't put all providers at global level, put them where they are needed).
  3. Server cache: React Query or SWR.
  4. Since Remix has arrived, Kent is promoting Remix, which can not be used with mobile app.
  5. Pros: No need for external library. Since there is a process to be followed for solving the state problem, there is less chance that people will put everything in global state which can happen when external library is used.
  6. Cons: Bad DX, lots of boilerplate, chances of error, component can't subscribe to subset of state (partially solved by using multiple ContextProviders and wrapping only the components which need them).
  7. This can go wrong if the state changes too often (live price graph) reference: Dominik React Query maintainer

Argument 2:

  1. useContext for Dependency Injection but not for state value propogation reference.
  2. When to not use Context.
  3. Basically, useContext can be used for Theme, AuthContext, etc. reference. But for state which might be updated frequently and, or if a component only wants to subscribe to a subset of the state, then probably go with Redux or Zustand. reference
  4. Redux tried to useContext in v6 for state value propogation and it caused performance issues. Now, they are only using useContext for passing a static copy of state. reference
  5. UI state problem? Lift state up -> Component composition -> Context if the state is not changing as much (loggedInUserData, theme) else go with Redux or zustand.
  6. Pros: Less chances of error, less chances of going wrong, better DX.
  7. Cons: Possibility of putting everything in global store when not needed, learning redux/ zustand.

Handling server cache:

Options:

  1. React Query: For component scoped server cache and for global as well if zustand is used.
  2. SWR: Similar to React query but minimal.
  3. Custom hooks which do the same thing: DIY.
  4. Redux thunk/ sagas/ RTK query: if redux is used for server cache that is supposed to goto global store.

Problems to solve:

  1. In either case, if the server cache is actually maintained as cache in the app. Then we will need to also maintain when any particular data becomes stale and how to fetch it.
  2. We may also face a scenario where fetching data between render might trigger another render. Or the scenario where in future we use suspense along with above data fetching and caching solutions.

React Query v SWR:

  1. React Query has a bundle size of 50kB vs 15kB of SWR
  2. React Query has mutation hook for server side effects (post, put, patch)
  3. All of the data that is cached is garbage collected if any query remains inactive for 5 minutes in React Query.
  4. querying, caching, polling, parallel querying, initial data, window-focus re-fetching, network status re-fetching are common in both

UI & UX:

There won't be any changes in the UI. UX however, will be consistently good due to lower chance of performance issues.

Architecture changes:

Whatever option is selected must be enforced by maintainers and reviewers in order to maintain consistency and sanity. Also, new developers must be introduced to the particular pattern we decide to follow.

  1. For the fist solution multiple ContextProviders will be created and wrapped around colocated and composite components.
  2. For the second solution, there will be ContextProviders for value that seldom changes, and either selectors (redux) or useStore hooks in case of Zustand.
  3. For both the solutions, all the data fetching will be done via hooks (useQuery-ReactQuery, useSWR-SWR, useCustomQuery-DIY hook), and not via useEffect + useState in the component.

Library dependencies

React Query

  1. @babel/runtime
  2. broadcast-channel: for sharing data between multiple browser tabs or Node processes
  3. match-sorter: sorts words

SWR:

none

Security concerns:

Testing & rollout:

  1. Since, both React Query and SWR use hooks, they can be tested using React Hooks Testing Library

@sakshambhatt
Copy link
Contributor

@ankushdharkar @shreya-mishra, did you have a chance to look at the RFC? If you find it to be exhaustive pertaining to the issue, then might we go ahead and have a discussion with some other members and start executing?

@shreya-mishra
Copy link
Contributor

@sakshambhatt let's discuss it at @10PM today if you are available.

@sakshambhatt
Copy link
Contributor

sakshambhatt commented Jul 31, 2022

@ankushdharkar , what will be the next steps for this issue?
Creation of data model, data flow is separate issue than state management, right?
Will we be asking people for their comments on the above doc?

@yesyash
Copy link

yesyash commented Nov 1, 2022

Approach 3:

make our own external store and link it using useSyncExternalStore ?
Instead of using a library like zustand/Redux.

@yesyash
Copy link

yesyash commented Nov 1, 2022

Approach 4

Use Jotai as the state management library to handle UI state. It can be a good solution when we start integrating different functionalities (modules) like goals, members site, status site as it allows us to create atoms that can be specific to each module & if we want to keep our state within our component tree.

Sharing a link from Jotai's official site comparing Jotai and Zustand as they can be very similar when compared from the outside.
https://jotai.org/docs/basics/comparison

@shreya-mishra
Copy link
Contributor

shreya-mishra commented Nov 1, 2022

Approach 5

Let's start with the Redux saga or Justand and implement the other management library and just compare which one is better, as RDS is all about learning, implementing, breaking, and rebuilding things.

@sakshambhatt
Copy link
Contributor

How would we measure and compare the performances of these different approaches?

@yesyash
Copy link

yesyash commented Nov 3, 2022

How would we measure and compare the performances of these different approaches?

how about testing the following metrics?

  1. Bundle Size.
  2. Memory usage.

@sakshambhatt
Copy link
Contributor

sakshambhatt commented Nov 3, 2022

Ankush has suggested to search for all the references related to state management in React Native app on the internet. Post that, we would ideally pick the strategy that is standard across the industry.
If we are not able to find good resources, that is an opportunity to write blogs on it.

@sakshambhatt
Copy link
Contributor

sakshambhatt commented Nov 10, 2022

@sakshambhatt
Copy link
Contributor

Redux team has been advising against Sagas generally...
https://twitter.com/acemarke/status/1618630292520177668

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants