What is the best way to solve this UI usecase using react hooks - tiles screenshot
I have tiles that each need to make request to backed API REST endpoints. The number of tiles is configurable for every module, so ideally I want to have some configuration with array of items like
{title, text, asyncRequestFunction}
and based on that configuration array I want to do multiple async and concurrent requests to load data.
Each tile should show some spinner when the appropriate request is in progress and show data as soon as they arrive, not after all the data are available.
Can I solve it by some currently available hooks like react-hooks-async?
What really gets in my way is that react hooks cannot be called in loop.
Not completely sure I am answering your question Jirko, because it's usually better to show some code example of stuff you already tried.
From top of my head, I would have container component where configuration is pulled. Then mapped array of tiles from configuration and rendered child components with whatever settings you need passed as props.
Like this each child component can take care of it's own fetching inside useEffect or any hook you use from the library.
Additionally hooks are not supposed to work inside of the loop, that's anti-pattern.
Related
Currently I have my parent components handling all my Axios calls, and I'll pass that data down with props. Should my child components be handling those requests individually in each child component, what is the best practice?
Should my child components be handling those requests individually in each child component, what is the best practice
There is no such rule which says that parent component should get all necessary data and pass that data down to all child components through props.
We can imagine a situation where we have top panel element which shows:
person name
weather temperature
current date
Yeah, if we make requests from each component, then we will have three API calls. So far so good. But on the next day, client says that he wants to show weather temperature in bottom panel. So we will have weather temperature at the top and bottom panel. It means that we will make 4 API calls. And it is not good solution.
What we can do? So if you are going to need to share the state across a lot of components then we could use state management library or useContext hook (it is simpler and easier to understand than Redux). Both have pros and cons.
If your application is not small, we can use state management libraries such as Redux, MobX, Zustand. However, it is completely okay not to use state management library if your application is not big.
Do You Really Need a React State Management Library?
It depends very much on which and how many components need the data.
Data on which many components depend and do not have to be fetched again and again make the most sense in a parent component.
Data which can be used very limited in a small child component should also be fetched in this component.
The same applies to data that is between these two extremes. A healthy balance prevents components that have nothing to do with the data from being unnecessarily misused as middleman. Furthermore, the parent components render all child components as well. It is therefore all the more important to make sure that the calls happen as selectively as possible.
For data that is needed in each component, I recommend a state manager (React's native reducer and useContext). This prevents prop-drilling, because the data can be easily made available in each component.
I would like to know of a good way to organize reactfire hooks (such as useUser or useFirestoreCollectionData) in a medium-sized application:
I could put hooks in a top-level component, and pass this information as props down to subcomponents (or use a Context to store state).
I could put hooks within each component when needed, so I would end up with multiple useUser or useFirestoreCollectionData hooks.
The second approach decouples some of the components, which is nice since our project is under active development.
However, I am not sure if reactfire or firebase client library has built-in deduplication, compared to libraries such as SWR or react-query. I would prefer to minimize unnecessary reads.
I like to use a offline first approach when using the Firebase databases. None of the awailable libraries could fit our needs so I made my own list of providers where all of them are decoupled. The main goal was:
to have all data awailable offline no matter if the app is online or not (this also increases response time for users)
to persist realtime listeners for RTDB and Firestore
when you have for example a list and go to a single item and back you probably don't want to stop the listener when leaving that list component and start it again when comming back. If you stop and start it the firebase SKD will load all data from the database.
You can find the providers and an example app here.
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.
I currently have a React app that I'd like to use SSR with. All but one component is pretty much static content, making SSR super easy. Everything but the component is rendered just fine and well right now.
My question is how do I go about rendering this component that needs to first get data? Because it's a complex SVG that gets rendered my line of thinking is that having it "update" once data comes in is a bad move, and it would be better for it to just not exist in the absence of data (with an error message).
So here's my plan: I can add a prop to the component to pass in data from a parent rather than keep it as internal state only. So if data is passed, no fetch request in the component is necessary. From there what I can do is take the static bundle output of the app and, when the page is requested, the server will request the proper data just as the component would. Once the data is received, the server can grab the component from the bundle with regex, add the data as a prop, render the component, and stick it back in with the rest of the already rendered static content.
Is this the correct way to do this? It feels a bit complicated, but that might just be how it's done. I'm not sure.
Your intuitions are correct. In current React (17.0), it's quite cumbersome to do SSR with data-fetching inside components.
What needs to be achieved on a conceptual level is that all data dependencies need to be known upfront, ie. before calling ReactDOM's render. This way, one can access the data in a synchronous manner which allows to do one-pass render on a server.
I don't quite follow your idea to "grap the component from the bundle with regex". One way of solving the data dependency problem is to inject the data into React tree from the root component (ie. ReactDOM.renderToString(<App componentStaticData={data} />)) and make the data-dependent component aware of the fact that it can just grab the data from there instead of doing (asynchronous) call. It's important to note that useEffects are not executed on the server.
Another idea to grab all the data dependencies is to do two-pass render. First one is used as a way to collect all resources used, then we await their completion and inject them as static data into send pass.
Third way is to use one of the React frameworks that provide SSR out of the box. You can have a look at (among many others) Next.js or Gatsby. Depending on your setup, this might be easiest or the hardest way to achieve SSR.
I need help with figuring out how not to make my react.js component rerender same images from Instagram and add them to the exisitng in the view.
I have a react-instafeed container in my react.js component, which is fetching 20 latest images from my Instagram account and renders them in a neat grid. The react-instafeed element is a wrapper around the popular instafeed.js framework and makes the same methods and configurations available in react.js environment.
On initial load it fetches the images and renders them. However, if the current route is refreshed (by pressing the button in the header navigation, for example), it fetches all 20 images once again and adds them in the view, and so on.
I tried dealing with it by setting something like 'loaded' in the state in the 'success, or 'after' methods of the instafeed, but that's clearly not working and is anti-pattern.
I tried doing it with componentDidMount, with the result of a doubled http call on initial rendering and 20x2 images at once.
Apparently, setting state is not the right strategy in this case. How could I either prevent the element from making a n-th call to Instagram, or maybe destroying the element on componentWillUpdate()?