I am trying to optimize my react code by fixing any memory leaks. I am using createAsyncThunk canceling-while-running to cancel requests, if my component unmounts.
I have three reducers inside two useEffect
hooks. One dispatches when the component mounts and the other two dispatches when the response from the first dispatched reducer arrives.
Below is my code:
useEffect(() => {
const promise = dispatch(bookDetails(bookId))
return () => promise.abort()
}, [])
// this is triggered when the response from the dispatched "bookDetails" reducer arrives
// and get stored in the "book" variable as shown in dependency array
useEffect(() => {
let promise1, promise2
if (book._id !== undefined) {
promise1 = dispatch(getComments(book._id))
promise2 = dispatch(relatedBooks({ genre: book.genre }))
}
return () => {
promise1.abort() // BookDetails.jsx:58:1
promise2.abort()
}
}, [book])
When the component mounts the second useEffect
gives me an error, given below:
BookDetails.jsx:58 Uncaught TypeError: Cannot read properties of undefined (reading 'abort')
at BookDetails.jsx:58:1
at safelyCallDestroy (react-dom.development.js:22932:1)
at commitHookEffectListUnmount (react-dom.development.js:23100:1)
at invokePassiveEffectUnmountInDEV (react-dom.development.js:25207:1)
at invokeEffectsInDev (react-dom.development.js:27351:1)
at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27324:1)
at flushPassiveEffectsImpl (react-dom.development.js:27056:1)
at flushPassiveEffects (react-dom.development.js:26984:1)
at performSyncWorkOnRoot (react-dom.development.js:26076:1)
at flushSyncCallbacks (react-dom.development.js:12042:1)
I tried few things but it didn't workout for me.
Since the promise1
and promise2
is assigned within the condition book._id !== undefined
, it has the possibility of not being assigned. Simple quick fix is checking a condition when invoking .abort()
. Something like promise?.abort()
or typeof promise?.abort === 'function' && promise.abort()
.