From 367237c39c357744ae2cbbb0ede068262b102bda Mon Sep 17 00:00:00 2001 From: jaieds <87969327+jaieds@users.noreply.github.com> Date: Mon, 14 Apr 2025 16:20:28 +0600 Subject: [PATCH] fix: Change in option doesn't reflecting on the frontend --- .../mention-plugin/mention-hooks.ts | 71 +++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/src/components/editor-input/mention-plugin/mention-hooks.ts b/src/components/editor-input/mention-plugin/mention-hooks.ts index 93fd2565..cc84906f 100644 --- a/src/components/editor-input/mention-plugin/mention-hooks.ts +++ b/src/components/editor-input/mention-plugin/mention-hooks.ts @@ -1,6 +1,15 @@ import { useEffect, useState, useRef } from 'react'; import { OptionsArray } from './mention-plugin'; +// Wrapper class for string keys +class StringKey { + value: string; + + constructor( value: string ) { + this.value = value; + } +} + type TBy = T extends Array ? U extends Record @@ -14,8 +23,39 @@ function useMentionLookupService( by: TBy = 'name' as TBy ): OptionsArray { const [ results, setResults ] = useState( [] ); - // Create an instance-specific cache using useRef - const mentionsCacheRef = useRef>( new Map() ); + + // Create instance-specific cache using WeakMap + const mentionsCacheRef = useRef>( new WeakMap() ); + + // Store reference to key objects + const keysRef = useRef>( new Map() ); + + // Track the previous options reference + const prevOptionsRef = useRef( options ); + + // Clear cache when options change + useEffect( () => { + // Check if options actually changed (not just re-rendered with same data) + if ( prevOptionsRef.current !== options ) { + // Options changed, clear cache + mentionsCacheRef.current = new WeakMap(); + keysRef.current.clear(); + prevOptionsRef.current = options; + + // Re-run search if we have an active search + if ( mentionString !== null ) { + // Trigger search with new options + lookupService.search( + options, + mentionString, + ( newResults ) => { + setResults( newResults as OptionsArray ); + }, + by + ); + } + } + }, [ options, by, mentionString ] ); useEffect( () => { if ( mentionString === null ) { @@ -24,7 +64,16 @@ function useMentionLookupService( } const mentionsCache = mentionsCacheRef.current; - const cachedResults = mentionsCache.get( mentionString ); + const keysMap = keysRef.current; + + // Get or create key object for this string + let keyObj = keysMap.get( mentionString ); + if ( ! keyObj ) { + keyObj = new StringKey( mentionString ); + keysMap.set( mentionString, keyObj ); + } + + const cachedResults = mentionsCache.get( keyObj ); if ( cachedResults === null ) { return; } else if ( cachedResults !== undefined ) { @@ -32,16 +81,26 @@ function useMentionLookupService( return; } - mentionsCache.set( mentionString, null ); + mentionsCache.set( keyObj, null ); lookupService.search( options, mentionString, ( newResults ) => { - mentionsCache.set( mentionString, newResults as OptionsArray ); - setResults( newResults as OptionsArray ); + // Ensure the key object still exists + const currentKeyObj = keysMap.get( mentionString ); + if ( currentKeyObj ) { + mentionsCache.set( currentKeyObj, newResults as OptionsArray ); + setResults( newResults as OptionsArray ); + } }, by ); + + // Periodically clean up old keys + if ( keysMap.size > 100 ) { + const keysToKeep = Array.from( keysMap.entries() ).slice( -50 ); + keysRef.current = new Map( keysToKeep ); + } }, [ mentionString, options, by ] ); return results;