React architecture - reactjs

This is more an architect question with react.js in mind.
Where would I place the following business logic ?
Once a user has authenticated and we then have access to their user entity. I would like to check a value on the user object and if null populate it will data I can only get on the client and then patch that object. All the code to get, patch an object are within alt.js stores. But this is business logic and doesn't feel right that it's part of the store.
I have considered a react component that is set as a component on the root react route. But it doesn't feel like it's the right place as it does not render anything.

This is not really a concern of React, like you said it is more of an architectural choice.
Like the previous posts have shared, you could use the React lifecycle methods. Perhaps a better approach is to use a state management library like Redux.
If you have yet to use Redux, I would highly recommend it! Although, it is not always the best choice, it seems to work for 99% of my use cases!
Good luck!

Have you used context before?
You could create a context component with a getUser function. This component will handle all the business logic for the User entitiy.
The beauty of context is that it does not need to be a parent or child of other components.
You simply import the getUser via context and you can user the function. IE any component that needs to know User context can do something like this.
componentDidMount() {
this.context.getUserInfo((data) => this.setState({ user: data }))
}
Another use case for Context would be a notifier. A notifier may need to be used randomly throughout your app, passing down as props whenever needed would be a nightmare.
Instead, create it as context, and import it as needed.
If this sounds like it may be useful, I will provide an example.
Further, you can checkout the react docs

Related

Add the auth state listener to every component that needs it or can I add it only to the main App component and provide it furtther as a context

I was wondering which one is a better practice for a React app with firebase, I understand from the firebase docs that I should add it on every page that needs it, bu I was thinking that it would be easier to provide it as a context to all my components since pretty much all of them are relying on the user state to display the right information. So which one is better ?
I have tried both but I do not know which one is better in terms of best practices or when to use each approach .
Neither of these is pertinently better than the other.
The Firebase SDKs cache the auth information already, so adding an auth state listener in each component does not require extra calls to the server.
But there's also nothing wrong in principle with getting the state once at a higher level component and pushing it down into child components that needs it. Just make sure to re-render those child components when the auth state changes.

What "data" should you pass with React context

The React doc's say that context is for passing data around without prop drilling
I get that usually that "data" will be some kind of state.
What other kind of data might you want to use context for?
Specifically, we have a service layer object that has a bunch of methods to interact with APIs and external libraries. Is there any benefit of wrapping these objects in context?
They seem to work fine just accessing them like any regular import but colleagues are saying they should be wrapped in context.
Context is useful to share data that won't often change across component avoiding props drilling.
For instance, let's say you have a modal component and you want to be able to control the open state of your modal in many components, you may want to provide a context for your modal component (that what react-modal)
For your question about benefits of wrapping services in contexts there is no real answer, it depend of your project structure and your state management,
if you're request consume context based data (token, cache or ids) why not but if you use other state management system and your services relies on it, I would say there is no reason to wrap your services in context.

Where should I put API call which is requesting user data

Where should I put get user data API call which is requesting user data such as username, email from JWT token stored in localstorage.
Should I call it from _app.js pass it to the components or should I create redux store and save these data.
Using redux only for that purpose is an overkill. You should create context and wrap components, which are using this data. Also there is hook called useReducer, combined with context API allows you to achieve redux behavior.
Passing user data down to components directly is not a bad idea if you have only 2 level depth structure which is often not the case.
For this purposes is a nice option to use tools like Redux or React Context API. That way you can access the global state from whichever component you like in the same way, which leads to more readable and maintainable code. For more information about Redux vs Context API, consider looking more in-depth to understand the differences and decide which one is more suitable for your case.
For me personally, the Context API can do the work in more of the cases which is fine. Also, it is already part of React, and it's not a dependency like Redux is.

use of Context alongside Redux

I am using Redux heavily in my application. I also have a very limited number of properties stored in Context:
username of currently logged-in user
screen geometry information (to adapt whenever browser window resizes)
Is this an antipattern and should I move everything over to Redux and dispense with Context altogether? I am inclined to answering yes. So the question is:
Are there valid use cases for using both Context and Redux in the same app or is it a code smell?
No I can't think of a single reason why it would be a good idea to use both.
Generally "if you are using Redux only to avoid passing props down to deeply nested components, then you could replace Redux with the Context API".
If you need more advanced features, like predictable state container, async actions and so on, then choose Redux.
Pardon the pun, but "context switching" between the two is only going to confuse you, your app and future developers on your app.
in your case, username stuff definitely could belong in a redux reducer and screen geometry information feels like it is basic enough to live in React and be passed down as props. although, this of course can be stored in Redux state too

React components with shared state that are far away

I am new to React so please excuse me if this is a noob question but I really could not find the answer in the DOCs or elsewhere.
Let's say I have two buttons with a counter that share the state but are far away from each other in terms of the placement in the UI.
The documentation says the common owner component for both buttons should own the state. It makes sense if the components are next to each other like in the example but what if my buttons are each part of a different UI group and are far away in terms of nesting? My state holder would be the root of the document and I would have to pass a handler function down through many layers. And what if I need to add new component somewhere else that also needs to know the state? Would I have to modify all the parent components in the way to pass the state down? That is tremendously impractical.
Without React I would have some global Subscribe/Publish pattern like jQuery Observer and all UI elements could subscribe/publish to it regardless of their nesting position.
How does React solve this?
Related question: If I need to load/save the state to DB, how do I pass a reference of the controller (or Whatever) to each React component that stores the state?
1 for global state you may use REDUX
Redux is a predictable state container for JavaScript apps
for connect/subscribe component with that state ,you should use react-redux
If components are far away in terms of nesting, you may connect/subscribe them to redux store, and take only neccessary part of state. They will update if only neccessary part is changed.
article that explains how you can do your case
to learn how to use redux you can watch this videos from creator of redux (Dan Abramov)
1.getting-started-with-redux
2.building-react-applications-with-idiomatic-redux
3.I definitely recommend to you discordapp rectiflux channel. because you allways can ask any question online.(there you can find contributors of that tools)
2 alternative way that less verbose then redux is MobX
MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming (TFRP). The philosophy behind MobX is very simple:
Anything that can be derived from the application state, should be derived. Automatically.
I suggest to look at the Flux stores. In short, stores are like model in your application. You can listen to change (subscribe) and also modify their properties (publish). You can see how it was done in example app.
A better option is to go with Redux.
Redux is enabling use cases like yours in a way simpler fashion :)
It will help you with all the state and make your life much easier.
Some good resources for learning:
The Redux Website
Video courses from Dan Abramov, the creator [Free]
Awesome course on Udemy [Not free]
Building Applications with React and Redux in ES6
And finally take a look at this youtube series [Free]
Managing state in the middle layers of your app should be avoided where possible. This data belongs in a store, which holds the global state of the app. Then each component accesses the state via its props.
The naïve approach to get the data down to the component is to pass the store through all the layers of your app "manually", i.e. through props.
Smarter alternatives exist, which use connected components, that access the global state through the context (as opposed to the props). Typically, the presentational component (your button component) is wrapped in a container component that handles this connection to the store, then passes the data in via props.
There are numerous frameworks that facilitate this process, links to which are already provided in the other answers.
If you are trying to share simple states, try this ( I am the author): react-provide-state
Otherwise I will recommend Redux. It has become the most popular tool for managing application states.
In the applications being working on, we use Redux to manage the main application states and almost all other states. But we use 'react-provide-state' for simple, UI only states like Modal, Checkbox states.

Resources