Created
January 17, 2022 23:38
-
-
Save JacobJaffe/01b480369ff8e2ca6c1e7a3476a378be to your computer and use it in GitHub Desktop.
React Native loading animation easy hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect, useRef } from "react"; | |
import { LayoutAnimation } from "react-native"; | |
/import { useState, useEffect, useRef } from "react"; | |
import { LayoutAnimation } from "react-native"; | |
/** | |
* | |
* Triggers a layout animation when the loading parameter changes. | |
* Returns `showLoading`, which can be used to gate content. | |
* | |
* @param loading | |
* @example | |
* ```tsx | |
* const showLoading = useShowLoadingAnimation(!data); | |
* if (showLoading) { | |
* return ( <Skeleton/> ); | |
* } | |
* | |
* // Note that this implementation is ideal for one-way flows of `loading`, false -> true. | |
* // To account for this, you'll need to cache `data` for a render, to be in sync with `showLoading`. | |
* // Otherwise, this will flicker. | |
* if (!data) { | |
* return null; | |
* } | |
* | |
* | |
* // This component will animate in when data becomes truthy. | |
* return ( <Content data={data} /> ); | |
* ``` | |
*/ | |
export function useShowLoadingAnimation(loading: boolean): boolean { | |
const [showLoading, setShowLoading] = useState(loading); | |
const firstRender = useRef(true); | |
useEffect(() => { | |
if (!firstRender.current) { | |
// Don't fire for first render! | |
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); | |
} | |
firstRender.current = false; | |
setShowLoading(loading); | |
}, [loading]); | |
return showLoading; | |
} | |
export const useLoadingAnimation = (loadingProp: boolean) => { | |
const [loading, setLoading] = useState(loadingProp); | |
const firstRender = useRef(true); | |
// This is a pretty simple way to have a nice animation between states. | |
// It might need tweaking to ensure that it only fires if the screen is currently | |
// foregrounded -- we don't want layout configurations firing in the background, | |
// animating other layouts. | |
useEffect(() => { | |
if (!firstRender.current) { | |
// Don't fire for first render! | |
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); | |
} | |
firstRender.current = false; | |
setLoading(loadingProp); | |
}, [loadingProp]); | |
return loading; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment