From e5d7014b9fcc7f82a4c1bf76b1c57583e87bab25 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Tue, 14 Mar 2023 23:51:03 -0400 Subject: [PATCH] fix(striker-ui): run 'set validity on first render' in useEffect --- striker-ui/components/InputWithRef.tsx | 28 +++++++++++++------ .../components/ManageUps/AddUpsInputGroup.tsx | 14 ++++++---- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/striker-ui/components/InputWithRef.tsx b/striker-ui/components/InputWithRef.tsx index 16f769aa..86ebbdca 100644 --- a/striker-ui/components/InputWithRef.tsx +++ b/striker-ui/components/InputWithRef.tsx @@ -5,6 +5,7 @@ import { forwardRef, ReactElement, useCallback, + useEffect, useImperativeHandle, useMemo, useState, @@ -166,15 +167,24 @@ const InputWithRef = forwardRef( [initOnFocus, inputTestBatch], ); - if (isFirstRender) { - const isValid = - testInput?.call(null, { - inputs: { [INPUT_TEST_ID]: { value: inputValue } }, - isIgnoreOnCallbacks: true, - }) ?? false; - - onFirstRender?.call(null, { isValid }); - } + /** + * Using any setState function synchronously in the render function + * directly will trigger the 'cannot update a component while readering a + * different component' warning. This can be solved by wrapping the + * setState call(s) in a useEffect hook because it executes **after** the + * render function completes. + */ + useEffect(() => { + if (isFirstRender) { + const isValid = + testInput?.call(null, { + inputs: { [INPUT_TEST_ID]: { value: inputValue } }, + isIgnoreOnCallbacks: true, + }) ?? false; + + onFirstRender?.call(null, { isValid }); + } + }, [input.props.id, inputValue, isFirstRender, onFirstRender, testInput]); useImperativeHandle( ref, diff --git a/striker-ui/components/ManageUps/AddUpsInputGroup.tsx b/striker-ui/components/ManageUps/AddUpsInputGroup.tsx index e0896c23..9d8e83ff 100644 --- a/striker-ui/components/ManageUps/AddUpsInputGroup.tsx +++ b/striker-ui/components/ManageUps/AddUpsInputGroup.tsx @@ -1,4 +1,4 @@ -import { ReactElement, ReactNode, useMemo, useState } from 'react'; +import { ReactElement, ReactNode, useEffect, useMemo, useState } from 'react'; import { BLACK } from '../../lib/consts/DEFAULT_THEME'; @@ -142,11 +142,13 @@ const AddUpsInputGroup = < ], ); - if (isFirstRender) { - buildInputFirstRenderFunction(INPUT_ID_UPS_TYPE)({ - isValid: Boolean(inputUpsTypeIdValue), - }); - } + useEffect(() => { + if (isFirstRender) { + buildInputFirstRenderFunction(INPUT_ID_UPS_TYPE)({ + isValid: Boolean(inputUpsTypeIdValue), + }); + } + }, [buildInputFirstRenderFunction, inputUpsTypeIdValue, isFirstRender]); return content; };