diff --git a/src/hooks/useImmediateState.ts b/src/hooks/useImmediateState.ts index 979d95247d..701a2aa18f 100644 --- a/src/hooks/useImmediateState.ts +++ b/src/hooks/useImmediateState.ts @@ -1,9 +1,18 @@ -import { useRef, useState, useCallback, useLayoutEffect } from 'react'; -import { isSSR } from '../utils'; +import { + useRef, + useState, + useCallback, + useEffect, + useLayoutEffect, +} from 'react'; type SetStateAction = S | ((prevState: S) => S); type SetState = (action: SetStateAction) => void; +// See https://github.com/reduxjs/react-redux/blob/316467a/src/hooks/useSelector.js#L6-L15 +const useIsomorphicLayoutEffect = + typeof window !== 'undefined' ? useLayoutEffect : useEffect; + /** * This is a drop-in replacement for useState, limited to object-based state. * During initial mount it will mutably update the state, instead of scheduling @@ -11,32 +20,31 @@ type SetState = (action: SetStateAction) => void; */ export const useImmediateState = (init: S): [S, SetState] => { const isMounted = useRef(false); - const initialState = useRef({ ...init }); - const [state, setState] = useState(initialState.current); + const [state, setState] = useState(init); // This wraps setState and updates the state mutably on initial mount const updateState: SetState = useCallback( (action: SetStateAction): void => { if (!isMounted.current) { - const newValue = + const newState = typeof action === 'function' - ? (action as (arg: S) => S)(initialState.current) + ? (action as (arg: S) => S)(state) : action; - Object.assign(initialState.current, newValue); + Object.assign(state, newState); } else { setState(action); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); - !isSSR && // eslint-disable-next-line react-hooks/rules-of-hooks - useLayoutEffect(() => { - isMounted.current = true; - return () => { - isMounted.current = false; - }; - }, []); + useIsomorphicLayoutEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); return [state, updateState]; }; diff --git a/src/utils/index.ts b/src/utils/index.ts index 6021f17728..49861b08fb 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,7 +1,6 @@ export * from './error'; export * from './keyForQuery'; export * from './request'; -export * from './ssr'; export * from './typenames'; export * from './toSuspenseSource'; diff --git a/src/utils/ssr.ts b/src/utils/ssr.ts deleted file mode 100644 index 9eef157da6..0000000000 --- a/src/utils/ssr.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const isSSR = - typeof window === 'undefined' || !('HTMLElement' in window);