From f192939671172c07019edb41ab5f19e38a862931 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Sat, 26 Dec 2020 10:39:01 +0100 Subject: [PATCH] Fix `Image.getSize` in `useEffect` cleanup --- .../Timeline/Shared/Attachment/Image.tsx | 47 ++++++++++++------- .../Timelines/Timeline/Shared/Card.tsx | 19 ++++++-- src/screens/Shared/Account/Header.tsx | 32 ++++++++----- 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/components/Timelines/Timeline/Shared/Attachment/Image.tsx b/src/components/Timelines/Timeline/Shared/Attachment/Image.tsx index e690fef5..b39df126 100644 --- a/src/components/Timelines/Timeline/Shared/Attachment/Image.tsx +++ b/src/components/Timelines/Timeline/Shared/Attachment/Image.tsx @@ -20,30 +20,41 @@ const AttachmentImage: React.FC = ({ }) => { layoutAnimation() + let isMounted = false + useEffect(() => { + isMounted = true + + return () => { + isMounted = false + } + }) const [imageVisible, setImageVisible] = useState() const [imageLoadingFailed, setImageLoadingFailed] = useState(false) - useEffect( - () => + useEffect(() => { + const preFetch = () => + isMounted && Image.getSize( image.preview_url, - () => setImageVisible(image.preview_url), + () => isMounted && setImageVisible(image.preview_url), () => { - Image.getSize( - image.url, - () => setImageVisible(image.url), - () => - image.remote_url - ? Image.getSize( - image.remote_url, - () => setImageVisible(image.remote_url), - () => setImageLoadingFailed(true) - ) - : setImageLoadingFailed(true) - ) + isMounted && + Image.getSize( + image.url, + () => isMounted && setImageVisible(image.url), + () => + image.remote_url + ? isMounted && + Image.getSize( + image.remote_url, + () => isMounted && setImageVisible(image.remote_url), + () => isMounted && setImageLoadingFailed(true) + ) + : isMounted && setImageLoadingFailed(true) + ) } - ), - [] - ) + ) + preFetch() + }, [isMounted]) const children = useCallback(() => { if (imageVisible && !sensitiveShown) { diff --git a/src/components/Timelines/Timeline/Shared/Card.tsx b/src/components/Timelines/Timeline/Shared/Card.tsx index 2f1d3cf6..cce4ae73 100644 --- a/src/components/Timelines/Timeline/Shared/Card.tsx +++ b/src/components/Timelines/Timeline/Shared/Card.tsx @@ -13,11 +13,22 @@ export interface Props { const TimelineCard: React.FC = ({ card }) => { const { theme } = useTheme() + let isMounted = false + useEffect(() => { + isMounted = true + + return () => { + isMounted = false + } + }) const [imageLoaded, setImageLoaded] = useState(false) - useEffect( - () => card.image && Image.getSize(card.image, () => setImageLoaded(true)), - [] - ) + useEffect(() => { + const preFetch = () => + card.image && + isMounted && + Image.getSize(card.image, () => isMounted && setImageLoaded(true)) + preFetch() + }, [isMounted]) const cardVisual = useMemo(() => { if (imageLoaded) { return diff --git a/src/screens/Shared/Account/Header.tsx b/src/screens/Shared/Account/Header.tsx index 2b26d42d..91e24b11 100644 --- a/src/screens/Shared/Account/Header.tsx +++ b/src/screens/Shared/Account/Header.tsx @@ -17,23 +17,33 @@ const AccountHeader: React.FC = ({ }) => { const [ratio, setRatio] = useState(accountState.headerRatio) + let isMounted = false + useEffect(() => { + isMounted = true + + return () => { + isMounted = false + } + }) useEffect(() => { if ( account?.header && !account.header.includes('/headers/original/missing.png') ) { - Image.getSize(account.header, (width, height) => { - if (!limitHeight) { - accountDispatch && - accountDispatch({ - type: 'headerRatio', - payload: height / width - }) - } - setRatio(limitHeight ? accountState.headerRatio : height / width) - }) + isMounted && + Image.getSize(account.header, (width, height) => { + if (!limitHeight) { + accountDispatch && + accountDispatch({ + type: 'headerRatio', + payload: height / width + }) + } + isMounted && + setRatio(limitHeight ? accountState.headerRatio : height / width) + }) } - }, [account]) + }, [account, isMounted]) const windowWidth = Dimensions.get('window').width