React Native state management (Redux, Context API or Graphql) - react-native

After I got into the basics of React Native and developed some components, I did some research on how state management is being organised in larger apps and am trying to find out what I should be focusing on to learn those days. At first it seemed to be obvious to me that I would be using Redux, but it seems a lot of people are happy using GraphQL in a way that makes Redux even obsolete after implementing it. Now there's also the Context API and I'm wondering what you would be choosing today when writing an entire new React Native app that would be interacting with 3rd pty APIs a lot.
Thanks and regards,
Dennis

The answer depends on a lot of different factors. There are some cases where choosing one over the other makes more sense, but ultimately the decision is up to you. Nevertheless, let's look at some scenarios where it might make sense to use each of these options.
Redux
Redux is best suited for applications that need complex state management and a single source of truth. Typically you would wrap your entire application in a Redux provider so that the state of your entire application changes when this store changes. So this is best used when you have state that is used in many different places throughout the app and needs to be available to every component. An example might be that of a game where a player's actions impact everything around them. Here you could dispatch actions to Redux when a player takes damage or levels up to increase enemy difficulty.
Context
Context is (in my opinion) simpler to use than Redux and is useful for sharing state between a group of components. This is not necessarily for the entire app, although it can be and would effectively be a simpler replacement for Redux in that case. Rather, Context is used in situations where you have deeply nested components that need state from a parent several layers up, or for components that aren't nested within eachother but need the same data in order to work together. An example of when to use context would be in designing an image editor. You could have an image component wrapped in a filter component wrapped in a crop component wrapped in a sizing component and not want to pass the props down to each level every time. So you would wrap the top most layer in a provider and have each nested component be a consumer. You could also have a toolbar that can change the sizing, filter, etc. and so they would also be consumers and would call functions passed in by the provider. The rest of your app would have its own state and would not change when this state changes.
GraphQL
This is useful if you need to pull in state from several differnt APIs or backend services and combine this state all at once. This is dependent on either fetching from a preexisting GraphQL API or by setting up your own to pull in data from your other endpoints. Since you said you would be interacting with a lot of different 3rd party APIs, you could set up an Apollo server to retreive data from them, or use a service like AWS AppSync with Lambda if you want a managed GraphQL service. The beauty of GraphQL lies in that you can query for only exactly what your application needs at any given time. So instead of the APIs dictating what data the client can access, it is the client that tells the APIs what it wants, and then GraphQL gets it in an efficient manner. A perfect fit for this style of state management would be a blogging application. Here you need to pull in information on an author, and get all of their posts, and get all of the comments on their posts, and get their user info, and then get how many followers they have, etc. Where each of these pieces of data would normally be served from their own REST endpoint, you would end up making dozens - and in some case hundreds - of requests to your APIs and pulling in a huge amount of unnecessary data. With GraphQL you can declare what you want in the shape that you want it and pull it into your app in a single request. This would save you a lot of trouble in trying to see if your APIs have all returned a certain piece of data yet or not, and so you don't have to write a thousand if/else statements in your components. Only one would be necessary. However, GraphQL tends to be much harder (in my opinion) to setup compared to using Redux and Context. So be prepared that there is a tradeoff here. When people switch from Redux to GraphQL, they usually switch to the Apollo library in order to make use of their local state management and cache systems. These are not technically a part of GraphQL but are rather just nice add-ons that Apollo provides.
So that's just a general overview of the strengths and weaknesses of using each option. Again, which one (or which combination) you end up using really is dependent on your app's requirements. My suggestion is to experiment and find out.

Related

How to persist cached data beyond a phone reboot or app closure using Redux Toolkit Query with React Native?

As the question suggests, I'm trying to figure out how to persist cached data beyond a phone reboot or app closure using React Native with Redux Toolkit Query. I've noticed that the cached data gets wiped in those scenarios. I believe that caching data beyond an app closure or phone reboot is a common practice.
I have thought about simply storing the data in client-side Redux using Redux Persist to get around this issue, without persisting the api slice. As this post indicates, persisting the api slice is a bad idea:
What happens when i use RTK Query with redux-persist?.
Any tips on this would be appreciated! Thank you.
Generally I can only repeat what I already said in the other issue:
I do not recommend doing this. Data from a server should be fresh, and this way it defitely won't be.
That said, we are currently working on SSR integration and that, too, will need similar functionality. So some kind of rehydration mechanism will be integrated, probably in Redux Toolkit 1.7 - but until then you have the choice between not keeping api data cached (again, my recommendation. No user wants to open an app and see data from five weeks ago - rather show them a loading screen!) or restoring it, but potentially ruining cache collection of said data.

Best practice for fetching data from API periodically and provide it globally (for every Screen)

I'm working on a game-companion app and I was looking for a neat way to fetch data from multiple APIs initiated by starting my app (and maybe also if the user is refreshing the current page with swipe-to-refresh).
The thing is, I planned a dashboard-style homescreen (mostly reduced data from every API), where the user can navigate to different pages (all fed with different API's) and get detailed information for the specific section. I'm not sure how I can provide the API-data 'globally'.
I feel like my main.dart would be way too overloaded, but i can't think of any other way.
What's your thought on that?
Few approaches:
You can use a persistent db and write a wrapper DAO over it that such that anybody with access to this DAO object can write and read from DB. Packages like sqlite help in this regard.
If you are adopting bloc way of state management in your flutter app, then you can create blocs which could be used to share data across your app. flutter_bloc is a good place to start with this.
Via Singleton , If you want a sensitive data that needs to be available within the app globally, then you can create a singleton class that provides read and write from a secure vault. For this secure vault, flutter_secure_storage is convenient or shared_preferences for non sensitive data

Vue: Where to call API?

I currently learning Vue and I am building a movie database app, where users can see movies fetched from an external API and sorted by popular and upcoming.
I have to call different URLs for both categories and I was wondering if I should do that in each component or a separate, third component where all the fetched data is stored?
Does it make sense to use Vuex for a small application like this or is there another best practice? Thanks!
IMHO, Use of Vuex is not about size of application, but the structure. If you want a clean app structure, keep vue SFCs as "simple" as possible. Any logic should be in Vuex and any complex function should be in utility classes.
When you're dealing with an application (not individual components) that utilizes an API, I would recommend placing the API and data hydration into Vuex. (or rather a separate function, but initiated by vuex)
This would allow any component to have access to not only the data, but the loading status of the data. Allowing you (for example) to use something v-if="dataIsLoaded" for components that expect the data to be there, and v-else for loading indicators
There are many resources online and here on stack overflow that will guide you in this. Without knowing how big your application is right now and how big is going to grow, it is difficult to suggest whether to use Vuex or not. In any case, where you make your API calls is / should be independent of your state management.
In general API calls in Vue applications can be made safely in the created lifecycle hook of the component.
created() {}
If you are not going to reuse the data from the API in multiple components, then you can call it in the component where it is needed. If you want to want to do it in a third component, it has to be a kind of wrapper around around your components for popular and upcoming and then pass the data received as a prop to these components.
Approach 1:
MoviesWrapperComponent: Makes the API calls and passes it down to other components
PopularMoviesComponent: Receives data from MoviesWrapperComponent
UpcomingMoviesComponent: Receives data from MoviesWrapperComponent
Approach 2:
PopularMoviesComponent: makes its own API calls.
UpcomingMoviesComponent: Makes its own API calls.
How I do it, is the Ajax calls in each method as in this way it's easier to handle the promisses and the scope of the components.
I'm using the popular Axios plugin, and i'm very happy with it. https://www.npmjs.com/package/vue-axios
I wouldn't use vuex if you just need to share data between a couple of components, but you can use it if you want to learn how to work with vuex.

Packing all dynamic data into a single Vuex store

I'm working on a web application which consists of various pages that rely on ajax calls (via AXIOS) for either fetching data from the server or communicating data back to the server. However, the data that is fetched from the server is 99% of times intact during the lifecycle of a session meaning that it will not be changed (i.e. only displayed to user while involving very low update frequency). Moreover, this data, is just pure text including links to contents, formatted as a JSON Object.
I have just found about Vuex, and I have been thinking about packing all these get Ajax requests scattered across different components and centralize them in a Vuex Store in a way that, when the application loads, all required data would be fetched from the server so that no more communication with the server to get such data during the lifecycle of the session would be needed (while only getting the contents such as images, audio, etc via links).
Is Vuex appropriate for this purpose? Is this a good idea at all (based on the concept of speeding up navigations)?
As mentioned in the comments, Vuex is meant to manage complexity and in your case you are planning to fetch 99% of the data at the beginning for your app. So, in client-server aspect, you totally don't need it. Keeping your data structured would be enough.
However, you have also the notion mutation in Vuex. The idea is that you can update the core data only using mutations. In this way, you are protected from unwanted changes and you have a better insight how/in which order your data is changing. So, if you have complex operations on your data (fetched from server and also your apps logic), Vuex would be a good choice.
There are also another interesting features for different kind of apps. Note that is just another trending way to keep your data structured. There are also another strategies but since Vuex is regularly maintained by Vue core team (and it seems to be also in the future), I would suggest it. Especially, if your app keep growing, you will love it more and more. After reading core concepts of Vuex (or better its logic behind Vuex: FLUX), you will have better insight about it.

Initialize vuejs app

I'm very new to vuejs world and I'm trying to move my existing application to vuejs.
I use Laravel as a backend framework. I got a lot of entities and settings, and in order to the app to work properly I need to retrieve from server some necessary data like user role etc. So basically I need to:
Hide the whole app and show a loader instead
Make few ajax requests in order to retrieve data from server
Store the data somewhere, so that it's accessible everywhere in vuejs app
Hide loader and run the app
The data might be changed though, for example, I have a team and team members. The list of team members used in many places. So if I add a team member the team member list should be updated as well.
So I don't want to have a global javascript variable for storing such data, because any modifications in this variable should affect the data-binding and stuff.
How could I achieve this?
Thanks
Your use case seems appropriate to using Vuex.
From Vuex documentation:
Vuex is an application architecture for centralized state management
in Vue.js applications. It is inspired by Flux and Redux, but with
simplified concepts and an implementation that is designed
specifically to take advantage of Vue.js' reactivity system.
In other words, it is specifically designed to handle situations such as:
The data might be changed though, for example, I have a team and team
members. The list of team members used in many places. So if I add a
team member the team member list should be updated as well.