From 0d325b5e3b186fdc18f6d7743aeabc2ad61c5e96 Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Mon, 9 May 2022 19:12:59 +0200 Subject: [PATCH] Prevent react hydration error Signed-off-by: Tilman Vatteroth --- .../loading-screen/random-icon.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/application-loader/loading-screen/random-icon.tsx b/src/components/application-loader/loading-screen/random-icon.tsx index dfda67f9c..27dcb29bf 100644 --- a/src/components/application-loader/loading-screen/random-icon.tsx +++ b/src/components/application-loader/loading-screen/random-icon.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { useMemo } from 'react' +import React, { useEffect, useState } from 'react' import type { IconName } from '../../common/fork-awesome/types' import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' import styles from './animations.module.scss' @@ -26,9 +26,21 @@ const elements: IconName[] = [ /** * Chooses a random fork awesome icon from a predefined set and renders it. + * + * The component uses a static icon in the first rendering and will choose the random icon after that. + * This is done because if the loading screen is prepared using SSR and then hydrated in the client, the rendered css class isn't the expected one from the SSR. (It's random. d'uh). + * To avoid this problem the icon will be chosen in an effect because SSR won't run effects. + * + * See https://nextjs.org/docs/messages/react-hydration-error */ export const RandomIcon: React.FC = () => { - const icon = useMemo(() => elements[Math.floor(Math.random() * elements.length)], []) + const [icon, setIcon] = useState() - return + useEffect(() => { + setIcon(Math.floor(Math.random() * elements.length)) + }, []) + + return icon === undefined ? null : ( + + ) }