All application data in single redux store - javascript

I'm new to redux.
I have an app with five pages and every page have some tables.
should I save all pages data in store even those pages not rendered currently?
If answer is yes, what happen when I have large data in total?(5000 records)
If answer is no, help me to understand it and how manage deferent page States.

There is no clear cut way to this problem as is with most programming conundrum.
storing all the state information in redux is alright and manageable especially if you don't really have a lot of states or moving parts in the store. but in larger applications, you don't really want to update the redux store every time someone clicks an input field, especially if that is a trivial state it is updating(like states of a text field like focused, pristine and dirty). getting a good ratio of stuff in the redux store and the local state store can get tricky at first but you'll get the hang of it with more experience, though a general rule of thumb is
does this state affect another component?
If you answered yes, then you might want to move that to redux. otherwise leaving it in the local state store is fine. As for your concern with dealing with large data, take note that you should not load ALL the data on page load. load only the things you need(better if you can preload these) and fetch additional data as needed.
i.e. if you have an index page that should display the top 10 most popular tv shows this season. instead of seeding your index page with all the shows in your database, just load the 10 most popular tv shows. then proceed to fetch data you need as you navigate around the app

Related

Is there a way to preserve DOM state of the component after navigating away and back in Angular

After researching the issue for a few days I've seem to have reached a dead end.
I'm dealing with, what I assumed, was a fairly common scenario: After user navigates to a certain page and makes some changes (content of an input field, scroll through grid data or even changing some editable cell values ), he navigates to different page. When user returns to original page, all of the changes must remain the same.
Now, that means that cursor in the aforementioned input field must be in the same place, scroll position in the grid and changed cell values, as well as any other changes user made, must be preserved.
Solutions like storing data in localStorage, using services or even custom reuse strategy will not work, because saving that amount of information contained in multiple sub components will be impossible.
Currently, I'm considering DOM manipulation, where rendered template will be moved to a container in parent component in onDestroy hook, and returned later in onInit. That, of course, is a hail Mary attempt and feels very unnatural.
I'm hoping someone had (and solved) this problem before because, like I've mentioned, it seams like fairly common use pattern.
There is not much option to do this in angular compared to React,
What I can recommend you is, store all the data in "environment" as object and when user routes back populate data from environment.
Usually I do this, when a component loads I store values in objects. When on destroy called all this objects goes to the environment under a one main object.
When oninit calls I am checking if object has values and restoring the page to where it was.
I think you are looking for Angular RouteReuseStrategy, where Angular can cache some routes state, without destroying the component state, so when ever the user visit the same route a cached view will be used,
RouteReuseStrategy Docs.
You can also check this medium article, implementing the required methods
Medium
for small amount data we can use services or localstorage as you mentioned
for large amount data we can go with
NgRx
https://dzone.com/articles/angular-app-state-management-with-ngrx
I use a service for this purpose, saving and restoring the state of the page from an object stored in the service but i haven't been able to figure out how persist the result of a user file upload where i am holding a user uploaded image
Pending file upload to cloud storage. Any ideas on solving this helpful as it seems like the cached file is cleared by angular navigation process

React Native Context vs Redux vs AsyncStorage

I am implementing an app where I can navigate to other users profiles. Obviously, entering to a profile have a cost for the database request, and also slows the user experience (having to wait for the db response to show the data).
Here comes AsyncStorage, a local database to cache objects and data from the DB. This API is deprecated, and some people is using redux with redux-persist instead...
In my app I am not using Redux, so to manage my purpose, I suppose I have to use AsyncStorage. But, what about React Context? Currently I have implemented a context provider "CurrentUserContext" which have a "VisitedUsers" map, in which I put the users data when I enter their profile (so to avoid unnecessary queries to the database, I only have to see if the data of that user is in this map). So, if a user want to see the most freshed data, he will have to refresh (the profile screen has a pull-to-refresh mechanism). Also, this context's life ends when the app is exited.
My question is: Is this a good option to use context for this kind of purposes? I have never seen anybody doing this... That is why I am doubtful.
From my point of view it's fine, since you really only have a short map (which gets done in a very short time) in a context that will last until the user closes the app or logs out.
Be careful, I ask it as a question, since I really don't know if this is a good practice. It should not be understood as "personal opinion".
Thank you.

What is a simple way for a high school student to handle persistent state in a simple HTML/JS app?

I'm a computer science tutor, with a lot of experience teaching Python and Java but without a lot of web experience. I'm now working with a high school student who has been assigned a project that he wishes to implement in HTML and JS. So this is a good chance for me to learn more about this type of application.
It's an application for taking food orders on the web and showing an illustration of your order. You choose a main dish and any custom alterations. Then you choose another course of the meal, maybe a salad and any alterations. And so on. The first page it shows you will show an empty plate. You choose a course to customize and it will take you to a page that shows options, then another page with further options, and so forth. Each time you are finished configuring an option, it will take you back to the starting page and show a picture of the meal so far on the plate (which was formerly empty).
The main part I'm unfamiliar with is handling persistent state. Although each page will have a unique structure of images (possibly a canvas) and buttons, it will have to remember the order as configured as it loads each page.
I'm wondering what a simple way of handling this is. This is a high school student with very little prior programming experience, and I'm allowed to help her, but it has to be within her grasp to understand overall.
Perhaps sessionStorage is the best bet?
Regarding possible duplication of Persist variables between page loads, my needs are a lot more complex than that question--I need to store more than a single global variable, and I may need a framework to simplify this. In particular, I'm interested in doing this a way that is simple enough for a high school student to understand so that he can implement some of it himself (at least some of it has to be his own work). I don't know if using a framework will make the job simpler (that would be good) or whether it will require more effort to understand the framework (especially relative to an inexperienced student -- not good).
Perhaps sessionStorage is the best bet?
If you want the state to be automatically expired when the browser session ends. Otherwise, use localStorage, which will persist longer than that.
It's important to remember that web storage (both sessionStorage and localStorage) only stores strings, so a common technique is to use it to store JSON that you parse on load, so you can have complex state. E.g.:
// On load
var state = JSON.parse(localStorage.getItem("state-key"));
if (!state) {
// None was stored, create some
state = {/*...default state...*/};
}
// On save
localStorage.setItem("state-key", JSON.stringify(state));
Note that this bit:
var state = JSON.parse(localStorage.getItem("state-key"));
if (!state) {
relies on the fact that getItem returns null if there is no stored data with that key, and JSON.parse coerces its argument to string. null coerces to "null" which will be parsed back into null. :-)
Another way to do it is to use ||:
var state = JSON.parse(localStorage.getItem("state-key")) || {
// default state here
};

Should data go in a redux state tree?

I am a bit lost on what to keep in the state tree of Redux.
I saw two conflicting statements on what to store in the state tree(s).
React doc tell us that only user input should be stored in state trees.
The original list of products is passed in as props, so that's not state. The search text and the checkbox seem to be state since they change over time and can't be computed from anything. And finally, the filtered list of products isn't state because it can be computed by combining the original list of products with the search text and value of the checkbox.
Redux doc tells us that we often should store UI state and data in the single state tree:
For our todo app, we want to store two different things:
The currently selected visibility filter;
The actual list of todos.
You’ll often find that you need to store some data, as well as some UI state**, in the state tree. This is fine, but try to keep the data separate from the UI state.
So React tells that we should not store data (I am talking about data of the todos) and, for me, Redux tells the opposite.
In my understand I would tend on the React side because both React and Redux aims to predict a UI state by storing:
all what can't be computed (eg: all human inputs) and are part of the UI:
checkbox value
input value
radio value
...
All minimal data that could be use to build a query and send it to the API/database that will return the complete user profil, friends lists, whatever...:
user Id
creation dates range
items Ids
...
For me that excludes all database/API results because:
that stands on data level
could be computed by sending the right (and computed by pure reducers) query.
So what is your opinion here?
React documentation about the View Component state, but Redux documentation about the Application state. So, there is no conflicts between definitions.
If we talk about Redux - you make all your components without state (and transform stateless root component to stateful with help of react-redux's connect function). If you have large response from the server and you show your data with pagination / filters, you can treat your application state as what you see on screen and not put all data in Redux store, only what you need to render (for example, 100 rows to show page and total number of rows to show pagination). There is no restriction for this. The whole data you can put into another place. For example, in another data container in web-worker (I make a full request in web-worker and fetch from there only needed data to display).
Added after question edited:
The original list of products is passed in as props, so that's not state.
In that example, the reason why list of products isn't state - it's already in props. It means that the one of parent components have this as state.
I feel that the problem is that originally Redux was pushed really hard, and some people were so purists, that they argued for separating everything to Redux and re-rendering the whole application on every change. And then we ended up with this response of the creator, which actually only added a confusion, because redux was and still is a de-facto standard for new react applications, and a lot of tutorials assume it.
So, I feel that people are pressured from each side, and often they do some things without real understanding why they should (especially newcomers creating constants, actions and reducers). So, for those who read it, please start without redux, and keep it just in local state (but try to keep in some component like DataContainer).
For those who need redux, rule thumb is to put all async data (so all requests go through redux), and data which is needed for independent components. If components obviously located nearby, keep it in a local state and pass as props.
Redux is a very helpful library, but it's power is needed only after you start to have at least several routes, different query options and some complex UI. Before that there is a good chance that you are overengineering (but, of course, if you are sure that you will exceed this size, feel free to start with Redux). And again, you'll literally never will want to put your slider or small dropdown position in the store -- react's state serves perfectly for it.

How to integrate Redux with very large data-sets and IndexedDB

I have an app that uses a sync API to get its data, and requires to store all the data locally.
The data set itself is very large, and I am reluctant to store it in memory, since it can contains thousands of records. Since I don't think the actual data structure is relevant, let's assume I am building an email client that needs to be accessible offline, and that I want my storage mechanism to be IndexedDB (which is async).
I know that a simple solution would be to not have the data structure as part of my state object and only populate the state with the required data (eg - store email content on state when EMAIL_OPEN action is triggered). This is quite simple, especially with redux-thunk.
However, this would mean I need to compromise 2 things:
The user data is no longer part of the "application state", although in truth it is. Since the sync behavior is complex, and removing it from the app state machine will hurt the elegance of the redux concepts (the way I understand them)
I really like the redux architecture and would like all of my logic to go through it, not just the view state.
Are there any best-practices on how to use redux with a not-in-memory state properties? The thing I find hardest to wrap my head around is that redux relies on synchronous APIs, and so I cannot replace my state object with an async state object (unless I remove redux completely and replace it with my own, async implementation and connector).
I couldn't find an answer using Google, but if there are already good resources on the subject I would love to be pointed out as well.
UPDATE:
Question was answered but wanted to give a better explantation into how I implemented it, in case someone runs into it:
The main idea is to maintain change lists of both client and server using simply redux reducers, and use a connector to listen to these change lists to update IDB, and also to update the server with client changes:
When client makes changes, use reducers to update client change list.
When server sends updates, use reducers to update server change list.
A connector listens to store, and on state change updates IDB. Also maintain internal list of items that were modified.
When updating the server, use list of modified items to pull delta from IDB and send to server.
When accessing the data, use normal actions to pull from IDB (eg using redux-thunk)
The only caveat with this approach is that since the real state is stored in IDB, so we do lose some of the value of having one state object (and also harder to rewind/fast-forward state)
I think your first hunch is correct. If(!) you can't store everything in the store, you have to store less in the store. But I believe I can make that solution sound much better:
IndexedDB just becomes another endpoint, much like any server API you consume. When you fetch data from the server, you forward it to IndexedDB, from where your store is then populated. The store gets just what it needs and caches it as long as it doesn't get too big or stale.
It's really not different than, say, Facebook consuming their API. There's never all the data for a user in the store. References are implemented with IDs and these are loaded when required.
You can keep all your logic in redux. Just create actions as usual for user actions and data changes, get the data you need and process it. The interface is still completely defined by the user data because you always have the information in the store that is needed to GET TO the rest of it when needed. It's just somewhat condensed, i. e. you only save the total number of messages or the IDs of a mailbox until the user navigates to it.

Categories