From 37b2b7efbbe7130c94e7bdc14e2c4bcd9be9c970 Mon Sep 17 00:00:00 2001 From: Hugo B Date: Thu, 7 Oct 2021 23:59:59 +0200 Subject: [PATCH 1/3] fix: infinite useColor re-renders Fix infinite re-renders when using rgb or hsv as initColor argument of useColor --- src/hooks/useColor.hook.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hooks/useColor.hook.ts b/src/hooks/useColor.hook.ts index 4620492..083dea5 100644 --- a/src/hooks/useColor.hook.ts +++ b/src/hooks/useColor.hook.ts @@ -24,23 +24,26 @@ export function useColor( model: M, initColor: C ): [Color, React.Dispatch>] { + // Store initColor in state instead of using it directly as a useEffect dep to avoid infinite re-renders when "initColor" is an object + const [initColorValue] = useState(initColor); + const getColor = useCallback(() => { if (model === "hex") { - const color = initColor as Color["hex"]; + const color = initColorValue as Color["hex"]; return toColor("hex", color); } else if (model === "rgb") { - const color = initColor as Color["rgb"]; + const color = initColorValue as Color["rgb"]; return toColor("rgb", color); } else if (model === "hsv") { - const color = initColor as Color["hsv"]; + const color = initColorValue as Color["hsv"]; return toColor("hsv", color); } return toColor("hex", "#000000"); - }, [model, initColor]); + }, [model, initColorValue]); const [color, setColor] = useState(getColor); From 9f20dfdd4766a8b28dd00a95d90c5ce0698e9b2e Mon Sep 17 00:00:00 2001 From: Hugo B Date: Fri, 8 Oct 2021 00:21:38 +0200 Subject: [PATCH 2/3] qa: typo --- src/hooks/useColor.hook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useColor.hook.ts b/src/hooks/useColor.hook.ts index 083dea5..f72d9c9 100644 --- a/src/hooks/useColor.hook.ts +++ b/src/hooks/useColor.hook.ts @@ -24,7 +24,7 @@ export function useColor( model: M, initColor: C ): [Color, React.Dispatch>] { - // Store initColor in state instead of using it directly as a useEffect dep to avoid infinite re-renders when "initColor" is an object + // Store initColor in state instead of using it directly as a useCallback dep to avoid infinite re-renders when "initColor" is an object const [initColorValue] = useState(initColor); const getColor = useCallback(() => { From 7c5adca50a50364fb8406f91983942deaa3d31fb Mon Sep 17 00:00:00 2001 From: Wondermarin <33459274+Wondermarin@users.noreply.github.com> Date: Sun, 7 Nov 2021 07:48:29 +0300 Subject: [PATCH 3/3] fix: A more concise fix --- src/hooks/useColor.hook.ts | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/hooks/useColor.hook.ts b/src/hooks/useColor.hook.ts index f72d9c9..c6a086a 100644 --- a/src/hooks/useColor.hook.ts +++ b/src/hooks/useColor.hook.ts @@ -1,5 +1,5 @@ import { Color } from "../interfaces/Color.interface"; -import { useCallback, useEffect, useState } from "react"; +import { useState } from "react"; import { toColor } from "../utils/toColor.util"; /** @@ -24,32 +24,18 @@ export function useColor( model: M, initColor: C ): [Color, React.Dispatch>] { - // Store initColor in state instead of using it directly as a useCallback dep to avoid infinite re-renders when "initColor" is an object - const [initColorValue] = useState(initColor); - - const getColor = useCallback(() => { - if (model === "hex") { - const color = initColorValue as Color["hex"]; - - return toColor("hex", color); - } else if (model === "rgb") { - const color = initColorValue as Color["rgb"]; - - return toColor("rgb", color); - } else if (model === "hsv") { - const color = initColorValue as Color["hsv"]; - - return toColor("hsv", color); + const [color, setColor] = useState(() => { + switch (model) { + case "hex": + return toColor("hex", initColor as Color["hex"]); + case "rgb": + return toColor("rgb", initColor as Color["rgb"]); + case "hsv": + return toColor("hsv", initColor as Color["hsv"]); + default: + return toColor("hex", "#121212"); } - - return toColor("hex", "#000000"); - }, [model, initColorValue]); - - const [color, setColor] = useState(getColor); - - useEffect(() => { - setColor(getColor); - }, [getColor]); + }); return [color, setColor]; }