I'm rendering a react component that sends a request on render (as well as when state changes), but also receives user input.
I'm adding an event listener to accept user input, however, it seems like the events are being blocked by the request being sent. Here's a code snippet of what I'm doing. In the body of the component, I return a simple <Loading/> indicator when the request is happening.
To summarize what happens, when the component mounts, I'm unable to capture user input until the request finishes. Further, on subsequent changes to user input, the input is blocked by the request.
Any thoughts here? Or advice on how to debug?
#Jaromanda X was correct in the thread above. In the render of my function component, when parsing the returned data (something like data.map()), I was making expensive cpu-bound calls. Pagination or caching the data will do the trick.
In functional components, you can think function body as the render() method of old class components. So, when you try to send api request in there, it blocks the rendering of the element. You should make api call in an useEffect() function. So, it will work after component mounted without blocking it.
Related
TLDR: Is there a way to signal to NextJS to render a component only on the server (and thus only show the pre-rendered HTML on the client)?
Motivation:
The reason I want to do this is because the render function inside of the component in question runs a lot of (synchronous) Javascript. I'd like for this Javascript to not be included in the client bundle. My desired behavior is that this component is rendered once on the server and the generated HTML is simply displayed on the client; it should never render on the client.
Things that I've tried / don't work:
getServerSideProps
It appears that, even when a page has getServerSideProps, it will still send the Javascript code to the client. My assumption is that this occurs because NextJS (incorrectly) assumes that some state update could possibly occur in the component on the client and therefore the client must have access to the Javascript code to render the component in such an event. Perhaps I'm doing something wrong here?
Static rendering
The page uses dynamic from the URL (imagine something like the delivery status page of a delivery website; there are hundreds of thousands of different deliveries and so it doesn't make sense for them all to be statically rendered)
Conditional Rendering based on typeof window
I don't think this helps with my particular issue as I'd like to skip rendering entirely on the client but still show the component as it was rendered on the server
Thanks so much for any and all help!
I am facing a challenge where I was requested to send page_view events (GA4) containing some information that is fetched asynchronously.
The challenge is because since the information is not there yet once the page renders, I can't fire the event until it's there. That's fine.
The problem
Since a page can have multiple components and these components can be fetching some data as well that I need to send, the only way I see to fire this event once the data is available is by relying on the redux store to check for when the data is there. So once it's there, I trigger the page view event.
Something like this:
const subscriptionsData = useAppSelector(
(state) => state?.[REDUX_API.KEY]?.[REDUX_API.SUBSCRIPTIONS]?.successPayload?.data
);
useEffect(() => {
sendPageViewEvent({ subscriptionsData });
}, [subscriptionsData]);
Now if a page has multiple components and other components are also fetching some data that I need to send in this same page_view event, this solution doesn't work anymore.
I did a lot of research but was unable to find a proper way to handle this scenario and I am starting to think the problem is that I am trying to send data that I don't have.
The only solution I can think of to solve this problem is too hacky:
Have a sort of configuration file where we check based on the route,
what kind of fields are expected to be sent to GA, but I am trying
to prevent this because maintainability is bad and likely to
developers to forget to do it.
In general, my main point is: Is it a bad practice to fire asynchronous data inside page_view events?
For click events it should be fine, but for page_view, even if you are doing all data-fetching in one single component in the page and could wait for it to fire the event there, you can't control that you might need in the future to fetch data in another component inside the same page, and then get this same data in the original function... you'd have to fire another event, which would mess up with data in analytics...
I have a question about making api calls with react. They say to make them in the componentDidMount lifecycle method, but if the component is already mounted, do I have to re-render it again somehow? What if I am making a get request and the component displays some data that it gets? Thanks!
when you set state after making the request the component will rerender
This is actually why useEffect() in react hooks is both componentDidMount and componentDidUpdate; a lot of people will correctly implement componentDidMount, but they'll forget to implement componentDidUpdate and you end up with components that you need to remount in order for them to function correctly when they should be responding to the changes in props via componentDidUpdate.
You only need to use componentDidMount for (automatic) initial API calls made on page load, you can still make any API calls via a user interaction like a button click etc.
When your call completes within componentDidMount, set the state to store your result. This will trigger the component to rerender. If your component relies on information from an api call, consider using a loader and clearing it once the call is complete.
I was curious to know if making an API request outside of the lifecycle/useEffect is a valid way to make the call?
https://stackblitz.com/edit/react-useeffect-button has two functional components, the parent component makes an API call and passes the data to the child component, initially specified the limit of data to be fetched from the endpoint as 2 and the parent component has a LoadMore function that is passed as a prop along with the data to the child component.
Using the react-slick slider to display the images in the child component and the Load button onClick will call the function LoadMore inside the parent component and then it makes an API call and appends the new data from API to the old Data. The load button will append one Image to the existing images.
is this a good way to make API requests or should it be done only in the lifecycle methods?
is this a good way to make API requests outside useEffect/lifecycle.?
It depends on your requirements.
should it be done only in the lifecycle methods?
It depends on your requirements.
There's nothing wrong making API request outside useEffect. But it should be done in some other function or it will cause the request to go on every re-render.
And if the response if being saved in a state variable.
Then it will go into the infinite loop.
When do we make the request in useEffect and when by some other function?
Requests that fetch data or send some info at the time of initialization of the component is supposed to be made in componentDidMount/useEffect
And requests that are supposed to be sent on some action (like in your case, onClick) so they are hit according to that event.
There's neither good or bad, it's all about your requirements.
If you are making an API call to get data from initial render then using a lifecycle hook is a good approach. In your scenario, you want to make an API request when hitting a button. In that case it can be a simple function without any lifecycle hook method.
The only key part here is that you are maintaining the state and rendering the view from the state.
This depends on your needs.
if you think whenever your params change,API call will be triggered.
in this case, you should set the API call inside the useEffect.
If you want your API call triggered on page load(ComponentDidMount). In this case, you should set API call inside the useEffect
Otherwise no need to set api call inside useEffect.
In your case no need to set API call inside useEffect. because you hit the API call when the user clicks the button. So no need to use useEffect.
I have a component with a couple of input fields that updates the state of the component using the valueLink={this.linkState('foo')} facility provided by React.addons.LinkedStateMixin.
Prior to this I was using the onChange handler to communicate the changes back to the server using a websocket connection, so I was wondering if I could replicate this behaviour somewhat and post the changes in the state back using a "state change listener" of some sorts?
Looks like the method I am looking for is componentDidUpdate()