I have some questions about the store in ReactJS/Flux implementation.
Basically, I have all my API request which use store. But sometimes, I think store is an overkill features.
A simple example :
I just want display a list of the five last user who have registered on the home of my dashboard. I never want to refresh this list until the user refresh the browser. Should I use a store just for that ?! Or maybe I can create a "global" store for my home page where I include all this little things like this (static display of data requested by the API).
I have another question about store, how much a medium-size application have store ? Because mine have already a lot of store (20-30).
You create one store by page ?! By models ?! By components ?!
Thanks for you response.
TL;DR: many Reducers, one Store.
You tagged this with Redux so I'm going to answer based on the assumption that you're either using Redux or want to use as your Flux implementation.
Regarding the number of Stores, from the Redux docs:
It’s important to note that you’ll only have a single store in a Redux application. When you want to split your data handling logic, you’ll use reducer composition instead of many stores.
So it might be that you want to create a home Reducer to handle all the API responses for your homepage and save those to your single Store.
In your simple example, probably you don't need a store, but I would still use one, as it makes your application scalable. You never know when you would be asked to add new features to it.
About your other question, it totally depends although 20-30 stores sound a bit excessive.
Personally, I use redux and I just have one store with multiple reducers which I combine using redux's combineReducers.
This answer is assuming a few things, but here is my attempt:
A store might be overkill in this case since there is no updating happening after the user refreshes the page. Seems like a static object to me. If you don't have a store already and want to keep going without one I would suggest (assuming you are using flux) to create your dispatcher events within the component that needs this list. The dispatcher will listen for events from your actions. I am guessing your actions make the back-end call to get the last 5 users so the action would then emit an event with the 5 users you are wanting. When the dispatcher receives the event you can set the list of 5 users within your component.
The use case for a store that I have found is when you have "living" objects that change with user interaction on your page. With a store it may be easy to live update your list of 5 users every so often based on an interval and it also serves a way of abstracting out the dispatcher logic from your component into a nice and neat store.
Related
I just got acquainted with MOBX and I'm trying to understand the principles of creating applications with the help of MOBX, using the example of a finished application. I had a question, because I noticed that each page of the app has its own store for orders (the difference is one field). It's definitely the same data. Is it right approach?
Previously, in React applications, I used one store, and any component could use data from it. In this one each page use its own store for specific data and it doesn't matter if we have already created a store with this data for another page.
I have never created duplicate data. But I'm not sure how it should look like with MOBX.
Thanks for help.
I want to understand how create store with MOBX correctly. Can we share one store between different pages/components?
I'm working with a react app and currently working with a feature. The main task is showing some charts by getting data from API. And these charts will show the last 30 minutes' data.
I have questions,
In this situation, is it necessary to store these data in the state by Redux, though it can be handled at components very easily? And every time I refresh or request, I get new data (log base data).
When do we make the mind to store data in state and when not?
A redux store is a singleton, thus a single source of truth that can be made available to all components in the whole react application. If your state is intended only for one react component then you don't need a redux store. A useReducer react hook allows to well reproduce the redux pattern in a single component. Stick with a useReducer hook for a single component and use redux library for a store available to an app composed of several components.
Redux is not designed for the specif role of a special type of data.
You can use still store your temporary (30 min) data into redux, and use it to cross your feeling the same as the rest of your data.
But in this case, you might need to reset data after 30 minutes or invalidate your cache, keep your eye in react-query and RTK-query handling these types of actions more easily for you.
If data is being used for many states or those data are being used by many components then you should use redux. You can still go without redux, it is up to you after all.
If you have various components and routes then redux will help you to reduce the codes and also make the codes simpler.
Redux will give the one store for all the components in the project to store and access the data which is better then context or props tricks.
Also if you want to achive something like if user opened two different tabs. Let it be same page or two different pages of your website and if user done an action on page A and you want that page A or page B opened in another tab should get that update then redux can let you achieve that. Context and props passing are not useful in this case.
https://redux.js.org/faq/general#when-should-i-use-redux
Redux is most useful when in cases when:
You have large amounts of application state that are needed in many places in the app
The app state is updated frequently
The logic to update that state may be complex
The app has a medium or large-sized codebase, and might be worked on by many people
You need to see how that state is being updated over time
React app Scenario
I have 2 views, UserLister and UserViewer. Both are at different urls. UserLister is a complex table (third party using ag-Grid), with fields, and sort and filtering. UserViewer is an exceedingly complex view with a ton of functionality that takes a while to load up. I want to make it really performant and user friendly to navigate back to UserLister after viewing an individual User. I want it to display all the same sorts and the same information as the user has set up.
To put it another way:
I want the changes that I (or any person) uses on listing page 1 to be available if someone navigates away and then directly back.
Idiomatic way to accomplish this?
How can I accomplish this best in react? is there some function of react-router that would apply here? I would prefer not to have to manage the ?100s? of different states that the UserLister has for sorting/filtering/selecting data manually.
React-router is routing library which manages browser history. You need another tool to save and share state between components. The idea is to make both UserLister and UserViewer to store and access information from some kind of global storage. So each time user enters specific Route data persists.
There are plenty of ways how to do that. Most idiomatic way is to use useReducer hook and then implement "vanilla" Flux architecture (aka unidirectional data flow) in your app.
If you don't want to write all boilerplate by yourself (no judgement here), you can look at Redux, which will do most background work for you.
Redux still requires some good amount of boilerplating. If you don't like it and feel more like streams and observables guy, you can use MobX, which implements reactive programming patterns for state management.
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
Flux design pattern has been such help in simplifying my web application. However I ended up directly calling web APIs for certain situations simply because Flux seemed such overkill for the job. I was wondering how others might have solved such problem in a Flux way.
As the diagram suggests, we created the Action via the Action Creator for all Web API calls. I will give an example scenario. Let's say there are 3 components that are interested in User Store changes at the moment. User clicks one of them to load a list of user's hobbies from the back-end. But I only want only that one particular UI component to display the list of hobbies due to the user's action. The other 2 components won't change at all. Traditionally this would have been a simple couple lines asynch call with a callback. If you are to religiously follow Flux for this,
You create an action via Action Creator with a specific reference ID
Fetch data via Web API
Upon receiving data, action is created using the Action Creator
User store listens to this result arriving via the action
Update the store
Fire store updated event, all 3 components react to that and check if that was for mine using the reference ID
then finally render with the data fetched in that 1 UI component
My app having many small parts that load data dynamically like this per user action, I decided to use Flux for things that many components have to share states with since the stores act as centralized state provider. How do you guys use Flux to do simple data fetches such as the one mentioned above?
There are couple of ways to solve this.
Let all the components receive the update and the component decide whether to update or ignore the update.
Split up your store and subscribe only to those which are need in the component. This approach can get messy with stores getting dependent on each other and simultaneous dispatch problem.
If you haven't used any flux library , redux is highly recommended. It solves this by allowing the components to subscribe to part of state(store) tree.