Skip to content

Instantly share code, notes, and snippets.

@JacobJaffe
Created January 17, 2022 23:38
Show Gist options
  • Save JacobJaffe/01b480369ff8e2ca6c1e7a3476a378be to your computer and use it in GitHub Desktop.
Save JacobJaffe/01b480369ff8e2ca6c1e7a3476a378be to your computer and use it in GitHub Desktop.
React Native loading animation easy hook
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