Skip to content

Commit

Permalink
Fix: Prevent empty renders in ServerSideRender component caused by ch…
Browse files Browse the repository at this point in the history
…anging props while already fetching markup (#35433)
  • Loading branch information
fabiankaegy authored Oct 9, 2021
1 parent ef26639 commit 0c5d687
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions packages/server-side-render/src/server-side-render.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,15 @@ export default function ServerSideRender( props ) {
const [ showLoader, setShowLoader ] = useState( false );
const fetchRequestRef = useRef();
const [ response, setResponse ] = useState( null );
const prevResponse = usePrevious( response );
const prevProps = usePrevious( props );
const [ isLoading, setIsLoading ] = useState( false );

function fetchData() {
if ( ! isMountedRef.current ) {
return;
}
if ( null !== response ) {
setResponse( null );
}

setIsLoading( true );

const sanitizedAttributes =
attributes &&
Expand Down Expand Up @@ -130,6 +129,14 @@ export default function ServerSideRender( props ) {
errorMsg: error.message,
} );
}
} )
.finally( () => {
if (
isMountedRef.current &&
fetchRequest === fetchRequestRef.current
) {
setIsLoading( false );
}
} ) );

return fetchRequest;
Expand Down Expand Up @@ -162,30 +169,35 @@ export default function ServerSideRender( props ) {
* the request takes more than one second.
*/
useEffect( () => {
if ( response !== null ) {
if ( ! isLoading ) {
return;
}
const timeout = setTimeout( () => {
setShowLoader( true );
}, 1000 );
return () => clearTimeout( timeout );
}, [ response ] );
}, [ isLoading ] );

if ( response === '' ) {
const hasResponse = !! response;
const hasEmptyResponse = response === '';
const hasError = response?.error;

if ( hasEmptyResponse || ! hasResponse ) {
return <EmptyResponsePlaceholder { ...props } />;
} else if ( ! response ) {
}

if ( hasError ) {
return <ErrorResponsePlaceholder response={ response } { ...props } />;
}

if ( isLoading ) {
return (
<LoadingResponsePlaceholder
{ ...props }
showLoader={ ! prevResponse || showLoader }
>
{ !! prevResponse && (
<RawHTML className={ className }>{ prevResponse }</RawHTML>
<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>
{ hasResponse && (
<RawHTML className={ className }>{ response }</RawHTML>
) }
</LoadingResponsePlaceholder>
);
} else if ( response.error ) {
return <ErrorResponsePlaceholder response={ response } { ...props } />;
}

return <RawHTML className={ className }>{ response }</RawHTML>;
Expand Down

0 comments on commit 0c5d687

Please sign in to comment.