So, currently, we send an API call to get user authentication data. User ID, Client ID, etc...
Then we pass this data to redux and load the user data into React Router through connect() and mapStateToProps...
Then each route gets this user data and passes it to the rendered component through props...
Then, in a lot of our components, we make more API calls using the user data.
However, most of the time, this data shows as an empty object {}
Is it best to pass this data down to components through React Router, or should we be getting the data from redux and mapStateToProps on each component that needs the user data?
I would pass the info from the store to the components that need it using mapStateToProps or a container.
Although this could be considered subjective, there is a real advantage of using containers instead of passing the props from Router: By properly using containers you can pass to components exactly the properties they depend on, nothing else, because any additional properties passed along through components that do not really affect how those components render or behave could be causing unnecessary rendering. Using connect you can "inject" the store information anywhere in the element tree, but using Router you have to pass it down from component to component.
Related
I am making a React Native app and I need the user data (fetched from firebase database) to be available right after the first screen and in many other screens.
As it is complete user object data, I do not think passing it via the navigator props is suitable. So I am searching for alternatives.
Can someone help ?
The best way to store and share global data is Context API or Global Context .
This new API solves one major problem–prop drilling. Prop drilling is the processing of getting data from component A to component Z by passing it through multiple layers of intermediary React components. The component will receive props indirectly . Context provides a way to pass data through the component tree without having to pass props down manually at every level.
To create a context, we use React.createContext which creates a context object. You can pass in anything as an argument to React.createContext.
import React from "react";
const YourContext = React.createContext("value");
To make this context available to all our React components, we have to use a Provider.
Every context object comes with a Provider React component that allows consuming components to subscribe to context changes. It is the provider that allows the context to be consumed by other components.
In order to create a provider, we have to import our Context.
How to push props to component without any connection and calls? Another page
I have profile and company employees structure i wanna do button what will show to users theirs place in structure, but this is two pages without any render and connections or calls like <OrgStructure employeeCode="test"/>
If you have two Components that share common state but can't be directly coupled, you should use a global state container of whom both Components can read from.
You should check out https://react-redux.js.org/. It provides a global state container called "redux store". Components can independently subscribe to the store and get updated whenever the data in the store changes.
I have a query i.e:
query me {
me {
username
email
}
}
now I need to share this data between components.
I guess I can:
create HOC withUserData and wrap other components
create a render prop component and wrap other components jsx
else?
It depends on where are places you want to share them, I mean if you want to share data in the same branch of the component tree, you can have a Container Component at the top ( Which holds your state and pass the data has props to the levels below).
If your components branch is very complex and it needs to travel down many levels then its a pain and not recommended too, in this case, consider using Context API
https://reactjs.org/docs/context.html
I would not recommend a HOC for this, HOC is not meant to share data, its meant to share re-useable functionalities.
Please check this, this has a bunch of best practices https://www.toptal.com/react/tips-and-practices
Well REDUX is another way but I would not recommend using REDUX looking at your need.
When to use REDUX?
Basically, you need to be using REDUX, when keeping the state in a top-level root component is no longer sufficient, like for example : ( you have two branches out from root component, one of the child components in branch A wants to access some state in branch B's child, then you need to move it to the root component and again pass it down, such cases are apt for REDUX ).
HOCs and Render props are not something that you would use to share data among components since each wrapper will have a different instance of the data whenever you create a component like
const MyComponentWithData = withUserData(MyComponent);
You would use HOCs and Render props mostly to provide a functionality which can be relevant to more than one components like detecting click outside of the component, or a PrivateRoute for authentication and so on.
However in order to share data you have options to use React Context, Flux or Redux. With the usage of React redux you can keep data in a store and read and update data from the components that want access to it. However if your app is not using Redux and you would want to share data only for a part of the application, you can simply make use of React Context. For more details on how to use it, you can read about it here
I have a react application which will contains dozens of screen for admin panel. I decided to open pages in tabs that integrated to react-router. When i change the current page and return back same page everything entered on inputs are being disappeared.
What is the best practice for this problem. It should be scaleable and must not require to write code in every page developed by a developer.
Also I use Redux for transferring userContext and appContext to every screen. Is Redux usable to store every input or other components' values?
It's possible to create store for keeping input valus. You may update does valus on input changes and check if the store object has value on componentDidMount you can import values from store to inputs.
React state is good for storing data inside a component and even to pass it to its children. It is not ideal for passing data among siblings. This is the exact case you have described above with dozens of components that do not share parent-child relationship.
The ideal solution for this problem is Redux. When you application state is stored in Redux, you can easily switch pages and not loose any data. Moreover, you can store the same Redux state in localStorage to prevent data loss due to browser refresh or shutdown. Lastly, if a need arises to persist your data in a database, fetch all the store values into props with mapStateToProps and pass them to backend.
I'm fairly new to React, and I was trying to create an app that functioned thusly:
The app consists of several Pages, with multiple Components on each Page.
One of these Components is stats, which can change as the user interacts with Components on the Page.
When a user clicks on a certain Component, they will be taken to a "different" page, which is really just another Page, with different text, data, etc. This is carried out through the browserHistory.push() method. I would like to be able to carry over the changed 'stats' component from one Page to the next, but I am not sure how to do so. Furthermore, since I set the default value for stats in the Page component, it seems that any attempt at passing the changed values into the new Page would result in the new values being overridden. Can anyone help me?
Thanks.
State should live above the level of all components that need access to that state.
Remember that one of the principles of React is "one-way" data flow down the component hierarchy. Essentially, data/state should live at a high level, getting passed down to child components and consumed as needed.
In your case, you have some "stats" data that needs to be displayed across multiple Pages. So, "stats" needs to be owned by a component above all of your Page components - perhaps at the root component of the app itself. Pages themselves would just take the data in and render it, potentially with some callbacks appropriate for editing the data.
Read a bit more about Facebook's philosophy for React in "Thinking in React" in the official docs: https://facebook.github.io/react/docs/thinking-in-react.html#step-4-identify-where-your-state-should-live
One option to consider is to use React Redux to store the state of your application. You would then use mapStateToProps (See Redux API for details) to map the state into props for your stats component.