Perform async operation on app exit in React Native - react-native

My application requires the data in redux store to be persisted on app exit, I am looking for a proper way to do this.
I tried persisting data on componentWillUnmount of root component but it did not work. It looks like the process is killed before persistence is completed.
I also tried if AppState could be of any use. It does give information about the background/foreground status of the application, but it did not help either
Of course, I can update by persistence on every update of store, but I think there must be a better solution.

Related

How to keep component in sync with AsyncStorage?

So I need to get a value from async storage to build my component UI and no problem with that. But, in another component I'll be changing this async storage value, but once I do it, I need the other component to re render and get the updated value from async storage.
I know that this can be done in react web using local storage but that's just possible because local storage provides an event listener which fires whenever it changes, but there is no way to attach an event listener to async storage.
So my question is, is this even possible to do? And if not, any suggestions on how to get this done?
I haven't worked with async storage, but typically you will use the observer pattern through a library like RxJS in Javascript.
Basically you create an observable to which you subscribe, and subsequently the observer gets notified of state updates to the observable.
You can check out the source code of this library that I just found for an example:
https://github.com/bassihassan/xreactive-react-native-storage/blob/master/index.js

What is the proper way to run a javascript file in the background of a react native app?

I am writing a react native app and want to have a js file that listens to a server, fetches data from that server, and deploys changes to a redux store that updates my react components based off of the new data. I am curious, where is a proper place to instantiate this object that listens to the server? Currently, I am instantiating it in the top level component of my app like so...
App File
In ControlBoard, I initialize the object...
Control Board
and then the DataModel responds to the server and updates the application state through redux.
I am running into problems with this approach (ie sometimes ControlBoard is constructed multiple times). Is there a better way to accomplish this?
A a far better approach is to use socket.io to listen to any changes from your server then mapping it to your state and finally rendering it on whichever component you want.
There are many examples online to get you started, maybe you can look at this and this for a start

Redux saga: How can i make sure only my saga is able to update a certain state?

I have a mobile app made in React Native, and I've just run into a best practice dilemma i've encountered many times while using Redux/Redux Saga. I would love if i could get someone else's thoughts on this.
For a new piece of functionality i'm implementing, i need to be able to tell how many times the app has been launched. This involves asynchronously retrieving how many times the app was previously launched from the device storage. If there's a new launch happening, i also need to add +1 to the number and store that in the device storage.
This is how i currently do it:
Dispatch appLaunched() action when app launches.
Redux Saga takes event.
Inside Saga: Retrieve how many times app was previously launched (appLaunchCount) from device storage (wait for async to finish).
Add +1 to previous appLaunchCount.
Store new appLaunchCount in device storage (wait for async to finish).
Dispatch put() with new appLaunchCount to reducer.
Update state with new appLaunchCount inside reducer.
My problem with this method is step 6. Technically any part of my app could dispatch a new app launch count to my reducer, with any integer, and the reducer would update the state just the same even though it didn't come from the saga.
My question is this: How can i protect my Reducers/Sagas/Actions so that only my saga can dispatch the action with the current appLaunchCount ?
P.S The only solution i can think of is writing my saga and reducer in the same file, and use private actions that only the saga and reducer can access. I would really hate to have to keep all that code together though.
Private actions aren't really a thing. The store is, by design, a global object. And since actions are just objects with a type property, anyone who can construct an action object of the right type can in principle dispatch an action and kick off your reducer.
What you could do is make the action have a type that makes it obvious that it's meant to be private. For example, maybe the action looks like:
{
type: '__PRIVATE_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__'
// You could tone it down a bit from this :)
}
That of course doesn't make it actually private, but at least if someone wants to use it, it's impossible for them to not realize your intent.
If you wanted to make it more secure, perhaps you could use a symbol as the type, and therefore only anyone with access to the symbol could construct the right action. For example:
const appLaunchCount = Symbol('appLaunchCount');
// action would look like:
{
type: appLaunchCount
}
But then the issue is making sure that symbol stays hidden, and can be accessed only by those who you want to access it. Similar to one of the things you mentioned, if you have the saga/reducer in the same file, then you could make sure that other files couldn't access this symbol; but once you start exporting it it becomes harder to control.

Which library is better for offline support: redux-offline or react-native-offline?

Need suggestion on which library to use for a large react native mobile app using redux ? redux-offline or react-native-offline ?
I need to regularly check connection status, render view depending on the connection status, add actions to queue when offline and run them when online, cancel actions if some contradiction is there, and persist/rehydrate data offline.
I am using redux-offline in my react-native project, it works just great. The feature that you are looking for all are presents like
It regularly checks for connection status
Add action to offline anytime (online \ offline)
Run the action as soon as device became online (moreover, you can decide the retry interval)
You can write your own discard method to drop any action based on your business requirement.
It uses redux-persist which automatically persist\rehydrate data. Also, you can provide your own store mechanism.
redux-offline is working just great for me, Sorry, I haven't used react-native-offline yet so can't provide you any benchmark.
I would suggest going for react-native-offline.
React-native-Offline provides :
Easier queue handling for actions based on a regex expression or a list of actions
Auto Triggering the online only actions , once the network is back.
Your Saga looks cleaner and readable, with both online/offline cases , on a maintenance perspective.
Redux-Offline provides:
It basically on separate online and offline actions
Each action and associated rollback needs to be handled
Both provides the redux-presist with connectors of your preference.
I have evaluated both, and for my use case I decided to go with react-native-offline. I liked its integration and ease of setup with redux-sagas, and it's offlineQueue was very convenient to have when you expect your users to conduct many operations offline.

ReactJS - Data Changing/Refreshing

I'm new to React, I think the basics have sunk in but I'm stuck on something. We're going to re-build one of our old systems and I'd like to do it in React.
Our system is an internal CRM, each set of client data is about a Mb in size, so efficiency is one of our priorities. The logic is done on a separate API, used by lots of different systems, so 99% of this front end is CRUD only.
(I hope I'm explaining this Ok!)
So onto my question. If I make a small change to a part of the client data, say I add an 'Audit' to the client... there is a chance that LOTS of other data changes. Complex enough that I don't want to replicate the logic both front end & API side.
Would I need to have the API return the full Mb of data, to have the root level app re-render all it's components? Or is there a more efficient way of doing it? Should I be setting up each component to periodically ping the API to check for changes individually?
I'm just a little bit lost where to start tackling the idea of it. Any help is much appreciated!
First things first - React Components rerender when any props or state field was changed.
If you change smth on the client-side and changes should affect server-side which important for user, then you do should updated your app view. To make it more smooth you can use shouldComponentUpdate method of Component's lifecycle to prevent unnecessary re-renders.
If server-side updates are not important for user (some meta data...), then you may not update the state of you application, by that you prevent re-renders.