From 0dfc388b7561bb7a5f62647b295463034e423d3b Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Fri, 1 Dec 2023 19:15:19 -0800 Subject: [PATCH] Move DelayedFreeze setImmediate into an effect Executing side effects in render is usually considered bad manners in react land, and given concurrency, could have unexpected results if renders are thrown away. This change makes it so setImmediate fires in an effect, and also cleans up after itself if for whatever reason the callback isn't fired. (although I think it's probably not possible with how setImmediate is implemented) --- src/index.native.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/index.native.tsx b/src/index.native.tsx index a51898a853..8e00ebb1f1 100644 --- a/src/index.native.tsx +++ b/src/index.native.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import React, { PropsWithChildren, ReactNode } from 'react'; +import React, { useEffect, PropsWithChildren, ReactNode } from 'react'; import { Animated, Image, @@ -194,13 +194,14 @@ function DelayedFreeze({ freeze, children }: FreezeWrapperProps) { // flag used for determining whether freeze should be enabled const [freezeState, setFreezeState] = React.useState(false); - if (freeze !== freezeState) { - // setImmediate is executed at the end of the JS execution block. - // Used here for changing the state right after the render. - setImmediate(() => { + useEffect(() => { + const id = setImmediate(() => { setFreezeState(freeze); }); - } + return () => { + clearImmediate(id); + } + }, [freeze]) return {children}; }