From 3621ec3fbe9d85ead877f3879626190b8ae86bb4 Mon Sep 17 00:00:00 2001 From: Cody Olsen <81981+stipsan@users.noreply.github.com> Date: Thu, 1 Aug 2024 09:39:44 +0200 Subject: [PATCH] fix: ensure search context provider value is memoized (#7200) --- .../components/common/SearchWrapper.tsx | 6 ++- .../search/contexts/search/SearchProvider.tsx | 39 ++++++++----------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/packages/sanity/src/core/studio/components/navbar/search/components/common/SearchWrapper.tsx b/packages/sanity/src/core/studio/components/navbar/search/components/common/SearchWrapper.tsx index 013b8f2adce..76f48e46330 100644 --- a/packages/sanity/src/core/studio/components/navbar/search/components/common/SearchWrapper.tsx +++ b/packages/sanity/src/core/studio/components/navbar/search/components/common/SearchWrapper.tsx @@ -44,7 +44,11 @@ export function SearchWrapper({ * Set shared `onClose` in search context */ useEffect(() => { - setOnClose(handleClose) + /** + * When using useState you have to use the function callback version of setState, + * otherwise it'll call your function and set the state to whatever your function return. + */ + setOnClose(() => handleClose) }, [handleClose, setOnClose]) /** diff --git a/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx b/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx index 4a4082f9299..87a028b8836 100644 --- a/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx +++ b/packages/sanity/src/core/studio/components/navbar/search/contexts/search/SearchProvider.tsx @@ -1,5 +1,5 @@ import {isEqual} from 'lodash' -import {type ReactNode, useCallback, useEffect, useMemo, useReducer, useRef, useState} from 'react' +import {type ReactNode, useEffect, useMemo, useReducer, useRef, useState} from 'react' import {SearchContext} from 'sanity/_singletons' import {type CommandListHandle} from '../../../../../../components' @@ -28,7 +28,7 @@ interface SearchProviderProps { * @internal */ export function SearchProvider({children, fullscreen}: SearchProviderProps) { - const onCloseRef = useRef<(() => void) | null>(null) + const [onClose, setOnClose] = useState<(() => void) | null>(null) const [searchCommandList, setSearchCommandList] = useState(null) const schema = useSchema() @@ -103,10 +103,6 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) { }), ) - const handleSetOnClose = useCallback((onClose: () => void) => { - onCloseRef.current = onClose - }, []) - /** * Trigger search when any terms (query or selected types) OR current pageIndex has changed * @@ -184,21 +180,20 @@ export function SearchProvider({children, fullscreen}: SearchProviderProps) { isMountedRef.current = true }, [dispatch, hasValidTerms, result.hits, terms.query, terms.types]) - return ( - - {children} - + const value = useMemo( + () => ({ + dispatch, + onClose, + searchCommandList, + setSearchCommandList, + setOnClose, + state: { + ...state, + fullscreen, + }, + }), + [fullscreen, onClose, searchCommandList, state], ) + + return {children} }