React JS componentWillUnmount Only Sometimes Called - reactjs

Is there a way to invoke componentWillUnmount every time I make a new request?
Right now, it is called only sometimes. It's not even called when I refresh the browser.
Situation:
I have a like/dislike module just like stack overflow's. Initially, I sent an ajax request every time a user clicks like or dislike. Because this was so slow and also because I had to disable the buttons to prevent duplications, I instead decided to do an optimistic update. Basically, I just update states when user clicks like or dislike, and I send the ajax request during the componentWillUnmount method. If it doesn't get called, all the likes and dislikes disappear :(

You don't want componentWillUnmount for this. If you're using Flux with React, it's pretty simple: when the store notifies the component that it has changed (after an Ajax request was made), you can ask the store if the update went through successfully. If it hasn't, you can roll back your optimistic update. Are you using Flux?

Just before updating the state, you can check the current state. If user already clicked like or dislike, do not send the ajax request. Otherwise, send the ajax request.
I observed componentWillMount and componentDidMount being called every time, but componentWillUnmount not being called on unmount immediately. Thus two or more react class instances of the same type were binded to the same dom object and I faced issues. componentWillUnmount gets called way later as a batch cleaning all binded objects. I am using react 0.14.2.

Related

React: Is there any way to cache components or prevent redundant HTTP calls with each render

The simple Code Sandbox below shows that navigating to a component triggers a fresh render. The React profiler states the components were rendered because they are continually seen for the first time. I understand this to be the correct React behavior, because each mounting/render generates new method references that triggers the re-rendering. However, this means that several http requests will be made despite nothing having changed. Is there any way to keep those requests from being made every time the user navigates to a component?
In the codesandbox I've tried using React.memo along with useCallback, and neither reuse the initial rendering.
Click the console tab to see each time the component renders, it makes a fresh ajax call.
https://codesandbox.io/s/github/pstephenwille/react-render-question
To avoid redundant HTTP calls you have to verify that your origin server does not have updated your local data. If you really want to just fire the HTTP calls once, you can e.g. execute them in your App component or pass a state and a callback function down to your Foo and Bar screen components that will ensure a singular call

Cache not updating in child component

Im working on a chat app that uses Apollo client and React
I made my Messages Window component run a cache update in the componentDidMount.
My goal is to update the unread count when the messages are opened. This updates when getting the message but the frontend UI needs the optimistic ui update.
I refresh the page:
First click causes no response...
Every click after that seems to update the previous.
Any ideas?
Here's my onload for the component
Did have setup redux in your app then call action at when user open message and you will get new data at componentwillreceve method via reducer then you can do what ever you want

reactjs : Fetching external data

I am learning how to use Reactjs and I read the following post :
https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data
When componentWillMount is used, it is written that The above code is problematic for both server rendering (where the external data won’t be used) and the upcoming async rendering mode (where the request might be initiated multiple times).
I do not understand :
How the request might be initiated multiple times because
componentWillMount is used only one time.
Why componentDidMount solves this problems. For the server rendering,
the external data won't be used also in the first render call.
According to the React docs, changing your component’s state in componentWillMount will not trigger a re-render. This means that if you make your AJAX call and set the response in your component state, it will not re-render, which means you won’t see your data in the DOM. (Remember that the component was initially created with an initial state which most likely didn’t have the data from your external data/AJAX call response)
You could argue that wouldn’t it be better to do my AJAX call to pull external data before the component mounts for the first time?
It wont be better because you don’t know how much time it will take to do your AJAX call. Your AJAX request could take longer to get the data than the time it takes the component to mount and therefore your data does not show up on your DOM as the component has already rendered and there is no re-rendering happening. Your AJAX request could take longer for any reason - your user is on mobile and has slow internet, some issue with your server is making it slow to return responses, etc...
Best thing to do is make your AJAX call in componentDidMount and make your component handle empty data (probably display a loading spinner) until your AJAX request returns the data, sets it to the component state and triggers a re-render! :)
If you read further down they explain a bit more why componentWillMount is problematic.
The above code is problematic for both server rendering (where the
external data won’t be used) and the upcoming async rendering mode
(where the request might be initiated multiple times).
But these may be rendered moot as react is essentially deprecating that lifecycle function come react 17, and thus currently is renamed to UNSAFE_componentWillMount and not recommended for use, but instead use componentDidMount to make your async data fetches.
Why does componentDidMount fix this?
Because the server is pre-rendering the components/JSX, but you don't want the component to fetch its data until after it is actually mounted and running in a browser.
react component lifecycle docs

React + Redux Saga refresh and re-render list when MongoDB data changes

I wanted the list of users to always be in sync with the MongoDB database,
I created an action that dispatches a refresh call to refresh the list of users.
What I have right now is an interval that dispatches the refresh call to refresh the list every 1 second, but I think it's a little hack to do that.
Is there a better way to refresh my list and re-render them through my React views?
What you are doing right now is okay but is expensive, specially if your browser tab is not active (please note that setInterval/setTimeout get less priority by browser if the tab is inactive or minimized).
You might need to explore using RxJS which has the capability to create periodic caller functions and you can subscribe to it in your react view.
Example - https://www.learnrxjs.io/operators/creation/interval.html

Appropriate place to dispatch action for fetching server data

I'm new to React and I'm trying to figure out the best way to request information from the server based on the URL. I'm using Redux and React Router v4.
Let's say I have a route /foo/:id, and a component Foo that will render something based on id. However Foo needs some server data related to id to do so. I believe the way to accomplish this would be to use mapDispatchToProps to create a function that takes id as input, does some async work, dispatches an action, and ultimately updates the redux state.
My question is: where is the most appropriate place to invoke the dispatch? In this scenario, there's no form submission or button click to kick things off. Originally I was thinking of including a check for the id data in render() and fetching if it was not populated, but this felt wrong due to the side effects.
You can do it in componentDidMount of the Foo component, similar to this example from the Redux GitHub project.
Your intuition is right that render is not a good place to do so. Most people do it in the componentDidMount lifecycle method of the component.
On a relevant note, you will also want to do fetching also in the componentWillReceiveProps method like what they did here. Reason being if your user navigated from foo/1/ to foo/2/, the component is already on the screen and will not be mounted again, hence componentDidMount will not be called again. The fetching for the second user will be done in the componentWillReceiveProps method.
i think the best way to do the dispatch inside the componentWillReceiveProps() which would help you fetch some data before the component renders
It seems your use case is well-captured by the react-refetch package which you can find here. It provides a higher-order component that allows you to specify dependencies at specific API endpoints and then resolves them when a new instance of your component is created.
Importantly it injects the data into your components props using a synchronous abstraction of a promise called a PromiseState. This will allow you to conditionally render your component depending on whether the data is say pending, fulfilled, rejected, etc.
This is not attached in any way to Redux, it skips that layer entirely, so do keep it in mind that the response is directly injected into the component and does not go through your redux store's state.

Resources