react-sdk
react-sdk copied to clipboard
Can't perform a React state update on an unmounted component
Hi.
I'm getting this Can't perform a React state update on an unmounted component Warning when I'm using optimizely. In a simple example, I created a hook like this:
import { useDecision } from '@optimizely/react-sdk';
const useOptimizelyFlag = flag => {
const [decision] = useDecision(flag);
return {
isEnabled: decision.enabled,
};
};
export default useOptimizelyFlag;
And then in my code when I use it like this:
const { isEnabled } = useOptimizelyFlag(MY_FLAG);
then I get the warning I mentioned. If I delete that line and just put const isEnabled = true then I don't get the warning anymore.
Also, the warning I see on screen is telling me is in the optimizely code.
I already checked this issue but it doesn't seem to relate to this particular case now.
Oh, and I tried updating to the last version (right now that's 2.9.1) but didn't help
I created an internal bug ticket (FSSDK-9622) to review.
@ManuViola77 sorry for the delayed response. Its been a while..
There have been some hook udpates in #273 to address some of the rendering issues related to hooks. Could you please update to latest version (3.2.2 right now) and recheck if the issue still persists!
If persists, could you please provide some implementation details (if possible) on how and where are you using useOptimizelyFlag hook so that I can reproduce it?
Thanks!
I'm having a similar issue using the 3.2.2 version and react 18
I consume Optimizely via a custom-hook "useOptimizely"
Use the returned provider and client on a component
And call useDecision on a child component. The hook works fine, but it warns about cleanup of assynchronous tasks
Hey @marcosfilho-hotmart, this might not be the exact reason for this , but you can optimize the way you are creating Optimizely instance in your custom useOptimizley hook.
Every time the parent component gets re-rendered, (in your case its the Card component) useOptimizely returns a new instance of Optimizely client.
To mitigate this, you can update your useOptimizely hook like following -
function useOptimizely() {
const [optimizelyClient] = useState(() => createInstance({
sdkKey: process.env.OPTIMIZELY_SDK_KEY,
eventBatchSize: 10,
eventFlushInterval: 1000,
}));
return { OptimizelyProvider, optimizelyClient };
}
This way useState hook will preserve the optimizely instance between re-renders.
Let me know if it helps your case!
Thanks!
Thanks for the answer @junaed-optimizely !
First off, as this might be a different issue from the main thread, would you like me to create a new issue?
The error persisted after making the changes suggested on your message, in fact the error started happening on almost every render instead of only ocasionaly. When executing manual tests locally, the error only happens when useDecision is called, if I remove it the error does not happen. Just for the sake of it, I have also tried extracting the optimize instance definition outside of the hook and the issue continues to happen.
@marcosfilho-hotmart , thanks for providing more detail on this. I will come back to this after some investigation!
Hi @marcosfilho-hotmart,
Here’s what I found about the warning and the useDecision hook:
The useDecision hook waits for certain promises to resolve. If the component unmounts before the promise resolves, this warning can appear.
Before React 18, this was considered a potential memory leak. However, the warning was removed in React 18 because it was often misleading. You can find more details in this explanation by Dan: React 18 Discussion.
I recommend re-checking if your react version is indeed 18.
Hope this helps!
Thanks!
Thanks for the update, that is indeed most likely the issue as the project is legacy and is still using React 17. We will be updating the application in the following weeks, but its great to know that this is not an actual memory leak.
Thank you again for the support and for the incredible work with Optimizely!