How to preserve state of a component in React? - reactjs

In my React project, I have a homepage which displays several blogs based on a topic. These blogs are stored in the state by making an API call on the basis of topic. On clicking on a blog, it takes me to the individual page for it.
Now what I want is that when I press back from the individual blog page, the earlier state is restored, i.e. I get the same list of blogs related to that topic which I had before and I do not have to make another API call.
How can I do this?

I suggest you use React.Context allowing you to store data in a global state.
The official documentation is pretty well written.

There are multiple options to preserve/restore the state while navigating the application. Sorted from easiest to the more difficult solutions:
1. Cache your API responses
This is probably the simplest change you can make and prevents your application from doing the same API request and re-uses the first response in each subsequent request.
The downside is that when your data changes, the cache needs to be invalidated. This can either be done manually or you can use a cache lifetime mechanism.
https://developer.mozilla.org/en-US/docs/Web/API/Request/cache
2. Wrap your application with Context
React's state is preserved as long the component is mounted. You can take advantage of this principal and store your state in a wrapping component. With React's Context you can use this state.
This is a low-level entry to Global State Management without installing dependencies.
3. Global State Management with libraries
The most future-proof, but somewhat difficult solution, is to use a global state management library like; Redux or Mobx

How do you handle the current topic? I'm thinking that it would be a good idea to manage the current topic in the route, like this:
/blogs/sports: list blogs related to sports topic.
/blogs/tech: list blogs related to technology topic.
etc...
This way you don't have to worry about state preservation, when you go back from a specific blog you can take the topic from the route and display only the blogs related to that topic.

Related

Is it necessary to keep all the requests in saga or you can have separate modules for requests not related to redux and saga?

As I understand if we make a request by using redux-saga, the response is going to be stored into the redux store. But it is a bad practice to store all the stuff in the redux store. So is it ok to create separate module with API requests and use them when you do not want to put response in redux store ?
I would appreciate articles on this topic (couldn't find it on my own).
Making requests in a file is totally fine in some cases. Just do it carefully in order to prevent interfering with app performance (if a component is rendered multiple time and you need just one request do it in the parent, etc.)
As for articles I couldn't find any to exactly this topic, but react docs have an example of api calls (please ignore the class one and check the hook example bellow). Now I would recommend you too use a service for this to abstract the fetch logic, but the idea is there and, while this cases shouldn't happen a lot, I don't see any reason to avoid this if you only need some data in a specific component and there is no use in saving it to the state .
EDIT:
You have runSaga which according to docs
Allows starting sagas outside the Redux middleware environment. Useful if you want to connect a Saga to external input/output, other than store actions.
So you don't really need another library. Regarding the architectural problem this is what I was trying to emphasis with the react docs. I don't know if there are any articles in this direction (on a quick search I couldn't find any either), but I think for most of the data you want a reducer to prevent unnecessary reloading of the same data.
However there isn't anything suggesting not to do it as far as I know (neither in docs, articles, etc.). Moreover, in some cases, this can a good thing, and the fact that no docs suggest otherwise is a prove in this direction IMO.
PS: Also a discussion about using saga without redux here

About calling API in reactjs

I have a question about calling API in react.
Example in the website. We have a lot of page. Each page has a lot of components. And each component has its own data need to get in server.
I see we have two way to call API is:
First. We call all API of each page in a root of each page then set the data to state. After that, we pass data to children Component.
Second. In each component, we call its API to get its data then set the data to component 's state.
So which is better. I need an explain about that.
Thanks you,
There are many ways to pass Data through out the components.
If the application is small and there are small number of child components you can go by making calls in Root folder.
There would be some components that always doesn't render and only rendered based on specific conditions at this point you can go by making calls from that component.
Using redux and redux thunk is always an option if the data is needed in many components and data can be accessed at any point of time.
As noted in the previous answers/comments you could do either one of these. If you plan to use redux it might be easier to chain the api calls in a single action w/ thunk that gets ran on main component load.
Context or Redux would do you well so you don't have to pass tons of data through prop levels.(prop drilling)
I would suggest Redux, IMO context gets too cluttered and by the time you've properly atomized your code to clean up everything you may as well have just went through the overhead of adding redux.
What you should ask yourself is-
Does it make sense to have all this data load at the same time?
Is it appropriate for some api calls to be made from the components that will use them?
You have creative license to do what works best for you.

What's the right approach for storing and accessing table data in a Redux store

I'm very new to ReactJS and Redux (but not development, in general). I'm trying to determine how best to approach a SPA I'm building.
My app will download datasets via API and display them in a spreadsheet. I'd like to use Redux to store the data. Is that the right approach? We could potentially be looking at very large datasets. Would it be more appropriate to only store the data that is currently rendered in the spreadsheet?
I'm totally lost as to an approach that would be efficient in terms of rendering speed and memory management as well as mindful of potential network issues as rows of data are requested from the API.
Thanks...
When you are working on a react/redux app, you generally will have two options to store your state: local component state or in redux. There are quite a few blog posts out there detailing when each is appropriate. This github issue comment from Dan Abramov, one of the creators of Redux, pretty succinctly sums it up
Use React for ephemeral state that doesn't matter to the app globally and doesn't mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft.
Sometimes you'll want to move from Redux state to React state (when storing something in Redux gets awkward) or the other way around (when more components need to have access to some state that used to be local).
The rule of thumb is: do whatever is less awkward.
Both component state and redux state can be used performantly, so I wouldn't worry too much about that when choosing. From what you've described, the questions I would ask are
Do I need to have multiple spreadsheets of data loaded, but not all displayed at once? For instance, maybe you have multiple tabs of spreadsheets and you want to be able to tab through them without having to re-fetch the data each time
Do I need access to the spreadsheet data in a lot of different places, or is it fairly localized?
Will I be able to modify the data in the spreadsheet, and if so, how difficult would it be to perform those modifications using redux and without?
There are quite probably other considerations as well. In general, the advice given is to stick with just using React local component state until it starts feeling awkward, and then move to redux at that point. Oftentimes, components state is all you need, and if not you'll get a better appreciation for situations where redux helps.

How to make redux-form (or Redux in general) work nice with a local database?

It's days or maybe weeks (reading articles, watching videos/talks) that I'm trying to understand how to use Redux and redux-form correctly but it's really hard for me to fully grasp the concept. Maybe my usecase is not well suited for Redux or maybe I'm simply missing something obvious.
What I'm trying to find is a good foundation for a large application. I'm fairly convinced about React, but Redux (and in consequence, redux-form) seems like a good solution for a problem that I'm not having. Still, everybody praises the Redux (or flux) concept, so I want to make sure that I'm not missing something.
Well, the application is heavily database-driven with all data readily available in the browser (it's a offline-first application).
I'm using a in-browser database very similar to NeDB plus a Mongoose-like ODM, but actually the database is a(nother) custom project that I want to open-source once it is stable enough (I do have implemented it already and it works very good so far).
The key points of that database (relevant to this question) are probably that it has all data readily available in the browser and that it supports "live queries" - that means that I can subscribe to database changes and up-to-date query results are pushed directly to any consuming component/handler. Furthermore, the database automatically synchronizes all data with a server in background (two-way), meaning that collections may change contents in any moment.
As UI frontend I'm using Material UI.
The application itself will manage quite a number of different collections and I need to implement a number of forms for the user so that he can edit single documents in certain collections. Depending on the context in the application the user will see a list of all documents in the current collection and alongside a form showing the details of the currently selected document in that list. That form will of course also allow changes of the document. The user will probably only edit (see) one collection/form at a time.
See this quick Mockup for easier understanding:
The list on the left is ridiculously easy to do with React and the live queries described above. It's also "reactive" in that it is always in-sync with the database. However, it doesn't currently use Redux at all. I'm not sure if that's bad or not.
When clicking any item in that list, the details should show up in the form on the right.
I like the redux-form (v6) concept, but I can't figure out how to feed the document data to the form. I know there is initialValues but I could not understand how to use it properly.
I guess I need to push the document data somehow into Redux so that it is reflected in the form. Do I need to "start" a Redux action to push the data into the store?
On the other hand, using classic React state to pass the document (a simple JS object) from the list to my form component seems radically simple to me. At the moment I don't see any benefit from having a global form state in the Redux store. But then, I probably need something else than redux-form (couldn't find anything comparable).
Redux with my database seems also redundant to me since in the end both are global data stores.
I do use Redux already for a handful states that have nothing to do with database contents, like application status indicators and to toggle a global drawer. I'm also using redux-router (and ultimately would like to link the current list selection an unique URI). Yet I'm having a hard time to find a harmonic link between Redux and the database/database-related components.
So, my question in the end is: What's a reasonable way to implement these parts of the application? Redux or not Redux? In either case: how can it implemented?
If all your data is available more or less synchronously locally, Redux might not be that great a fit for your application.
However, if you want to use Redux Form, which provides a lot of form state management out of the box, you will need to use Redux, even if you only use it for the Redux Form reducer.
To initialize your form, you can either pass the values in via an initialValues prop to the decorated form component, or you may also call dispatch(initialize(formName, formValues)) yourself.
you can use the following package I've written:
https://www.npmjs.com/package/redux-offline-wizard
the base idea is to:
1) save redux to browser storage and rehydrate (reload from storage to redux store)
2) add a new branch to redux store to implement an outgoing queue for requests. any async XHR action will add a request to queue. Queue requests will be sent when user is online or comes back online and will be retried if failed because of network conditions

best practices for keep states of page in react-router application

I Have react app which contains many pages. For each page i added store. I using params from url for example photoId then passing to actioncreator which call service and then dispatching data to store. In page component i have store listener. Store imiting change and listener calling render for new state.
Store and action creator relates to this page only. How to create pages more simple?
Thank you!
The Flux model (using actions, dispatcher, and stores) works well for larger apps where a data fetch may affect many components and pages. If you think your app will grow then it may be worth the extra verbosity. If you're keeping your app small then composing plain React components is a great way to keep things simple and there is nothing wrong with doing it as long as you separate the data operations from the display, the way your linked example showed. Have fun!

Resources