Lets say we want to have one instance of the application and multiple tenants trying to access same features but also have some level of customisation and of course data isolation. In short Basic SaaS model.
Tenants will probably be identified by subdomain/domain and/or by querystring.
So the main question (which is rather specific):
What are common approaches onto implementing a multitenant environment using React + Redux ?
Thinking loud:
How to approach/structure the Application Store.
How to deal with tenant specific configurations
Do I need to have some sort of a TenantContext available somewhere at hand.
How to ensure proper level of isolation and avoid race conditions?
What else should be kept in mind while developing it?
Any thoughts, ideas, past experience, advice, are highly appreciated.
Thank you!
A typical Redux store usually only reflects persistent data, and contains application-specific data, like which tab is active or what is the value of that field. But in case of persistent data, that's an interesting question. I believe React and Redux are simply not for that. But even though, there's an interesting solution for that: Relay and subscriptions.
Relay connects your components to a GraphQL source of data (typically remote), and then you simply access props that are seamlessly injected into component and given values from the data storage. With subscriptions, any update in the data storage causes its delivery to a connected component via a subscription established between the app and the GraphQL server.
Now, you can add an extra layer for multitenancy and synchronize data between nodes on a lower level, completely unrelated to React. The only thing now is that you'll need to listen to every update and send subscription updates, and there's no nice "single-click" solution for that yet.
You can see this discussion to get an idea how you can update a subscription. Good thing is that, on the client-side, the app will simply react to updated props with a connected component being re-rendered with new props.
Related
I'm currently building an e-commerce react application, where users can sell pre owned stuff to each other. A typical workflow from a user perspective for creating and managing ads can look like this: A user creates an Ad -> The Ad is uploaded to a database -> The user fetches his ads from a database and views them in a list -> He decide to change something in an Ad, clicks it and gets a form with the ad data (fetched from database) that can be edited.
My problem here is that I'm really confused about what to keep in redux? The purpose of redux is to simplify data flow, data that is needed in multiple components should be stored there. But if I always fetch the data i need from database (as for example when a user fetch a list of his ads or the ad data that can be edited), isn't redux just an unnecessary step then?
I want to be consistent throughout my code about how I'm fetching data. Right now I've been using redux to store all my data fetched from database, keeping all my API calls in different actions. The data fetching however get really troublesome when it comes to fetching data from the database that then should be editable by the user. To make fetched data editable, it has to be stored in the components local state, so storing the data both in redux and local state feels very inconvenient.
I've searched the web for specific guidelines for the but I'm not getting any wiser. To be honest I don't think I've understood how to use redux properly. I would be really grateful for some advice on this matter.
Primarily its used for application state management. You need to consider your usecase and yourself simple questions i.e
Do you need that state for rest of the applications?
Will other components get affected by these states?
How often your data will
change?
Are there other users using the same data and can update it?
Do you need to cache the data to prevent refetching?
The view built on top of it is a reflection of that state, but does not have to exclusively use that state container for everything it does.
For example, in your case, you will need to keep your api's responses into redux state if you want to pass that state to other components and you dont want to do the same API call again and again.
But, if your data changes so often and you need refreshed data everytime you should not keep it in the redux. Otherwise you will end up having stale data on different screens.
Note :
There could also be other possibilities that can be consider but this is some very basic info that I thought will be useful for you to take a decision
It opinions based questions .
Need one suggestion.
In Reactjs, is it right approach to use redux for state management and for API call use Apollo + GraphQL?
You have to distinguish between view state (e.g. search field, popup, toggle) and data state (e.g. remote API). Whereas Apollo is mainly used for data state, Redux/MobX/React's Local State are used for view state when used in combination with Apollo Client. If not used with Apollo Client, these solutions can be used for the remote data state too. However, Apollo Client introduced apollo-link-state which can be used for the local view state too.
If your application is purely remote data driven and uses a GraphQL backend, Apollo Client can be sufficient for your application.
If you have a few view states in your application, mix in React's local state management.
If you have several to a lot of view states, use Redux or MobX for your view state or try out apollo-link-state.
That's certainly possible and the natural thing to do. We use this same setup and we found we don't have to use Redux very much anymore.
We used to use Redux to store our API responses (the data) as well, but now Apollo manages that for us.
So our Redux store is now only used for the actual UI state (e.g. routing state, user preferences for certain views, whether something is enabled or not etc).
All data is now retrieved by Apollo and kept in its own internal Redux store, which it uses as a cache. This works great and nicely separates UI state from data state.
I suggest Apollo GraphQl because it has many benefits:
Eliminate Boilerplate
No more action creators, async handling, and request waterfalls. Just ask for the data you need with a GraphQL query, and it shows up.
Validation across the stack
Identify breaking changes in your API before they are deployed, and statically validate data fetching across all of your frontends.
Understand API usage
Learn how your backends are being used with field-by-field granularity. Find and address performance hotspots easily.
Pull complexity out of the client
Put computed fields, data transformations, and security logic into your API so your frontends don't have to reimplement them every time.
Incrementally evolve your API
Add fields to GraphQL as you go and deprecate old fields when you no longer need them. Mock some or all of your API and build the frontend in parallel.
Improve performance
Fetch exactly the data you need, no more and no less. Improve performance with GraphQL-specific caching and optimizations across the stack.
For more Information Read GrapQl Apollo Doc
https://www.apollographql.com/docs/
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
I'm not a frontend developer and have not used react or any flux implementations as I'm not sure if they will do what I want. I'm trying to wrap my head around how to use react to render backend changes that are external to the client, ie changes by another user. I see how react works to handle the view when the client takes an action, but I'd like to render changes from the server/other users without long polling (similar to how meteor works with two-way data binding).
My solution was to create a pub/sub system on the backend that will push changes to the clients if they're subscribed to the appropriate channel. This could be accomplished by analyzing database queries/backend actions and their resulting changes as is done with Asana's Luna. My friend told me that I can simply do this with only using an implementation of flux. If he's correct, I must be misunderstanding what flux actually does. To me, it seemed that it only reflects changes based on the actions of the 'current' client.
You are right. Flux is simply a way to manage application state in response to different actions. How you would trigger those actions is out of its concern. pub/sub server in this situation is a right way to go. You can take a look at Firebase - google non relational database that has lots of SDKs for different platforms and can notify client of changes done by other users. But anyway it works as a pub/sub server =)
I have been reading about React and Redux lately. It looks very interesting and I'd like to use it for small personal projects. One question I keep coming back to is, when does data get saved to the database (or some sort of persistent storage)?
Most tutorials explain components, props, state but they I've not found a lot of solid information about saving said state to persistent storage. Some articles mention local storage but what happens when that is cleared? All the user's data is gone . . . ?
Eventually, a database has to be used at sometime, right?
I have been looking into Axios to help with the API backend. Is this a good option? Is there someway to save to local storage instead so the user sees the UI update instantly and silently call an API endpoint after the fact?
Open to ideas and suggestions. Thank you!
This really is a broad topic but you're right that the internet is lacking in examples of data persistence. One reason is that neither react nor redux are frameworks that help with these; meaning it's a great application of the libraries but are not core to the abstract ideas they present.
That's not to say it's undoable, quite the opposite. With the help of redux middleware this becomes a fun task that works flawlessly with the rest of your application. There are many different ways of implementing data persistence so I'll just explain one here, which I use in my own apps.
CouchDB + PouchDB + middleware
CouchDB: simple document storage in JSON format
PouchDB: syncs your localStorage with a CouchDB instance to automagically allow offline use
Since databases introduce stateful behavior, redux suggests using middleware to not muck up your store with state kept outside itself. In this middleware you would sync up your DB instance to the store. This middleware simply reads the data in the DB and fires actions to insert it into the store. Your application then fires actions that the middleware picks up and uses to store data in its DB. Finally, the DB updates the store with the new data it inserted/updated/deleted.
It's a simple yet powerful way to persist JSON serializable data to a DB while maintaining a redux store.
Use react-persistent-store-manager. Uses pull state and localforage for persistent data. It's quite straight forward.