fix: sync FileUploader context with props to fix inconsistent file parameter state in “View cached variables”. (#26199)

This commit is contained in:
Wood 2025-09-25 22:43:26 +08:00 committed by GitHub
parent eab6f65409
commit fb8114792a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 3 deletions

View File

@ -1,6 +1,7 @@
import { import {
createContext, createContext,
useContext, useContext,
useEffect,
useRef, useRef,
} from 'react' } from 'react'
import { import {
@ -18,13 +19,11 @@ type Shape = {
export const createFileStore = ( export const createFileStore = (
value: FileEntity[] = [], value: FileEntity[] = [],
onChange?: (files: FileEntity[]) => void,
) => { ) => {
return create<Shape>(set => ({ return create<Shape>(set => ({
files: value ? [...value] : [], files: value ? [...value] : [],
setFiles: (files) => { setFiles: (files) => {
set({ files }) set({ files })
onChange?.(files)
}, },
})) }))
} }
@ -55,9 +54,35 @@ export const FileContextProvider = ({
onChange, onChange,
}: FileProviderProps) => { }: FileProviderProps) => {
const storeRef = useRef<FileStore | undefined>(undefined) const storeRef = useRef<FileStore | undefined>(undefined)
const onChangeRef = useRef<FileProviderProps['onChange']>(onChange)
const isSyncingRef = useRef(false)
if (!storeRef.current) if (!storeRef.current)
storeRef.current = createFileStore(value, onChange) storeRef.current = createFileStore(value)
// keep latest onChange
useEffect(() => {
onChangeRef.current = onChange
}, [onChange])
// subscribe to store changes and call latest onChange
useEffect(() => {
const store = storeRef.current!
const unsubscribe = store.subscribe((state: Shape) => {
if (isSyncingRef.current) return
onChangeRef.current?.(state.files)
})
return unsubscribe
}, [])
// sync external value into internal store when value changes
useEffect(() => {
const store = storeRef.current!
const nextFiles = value ? [...value] : []
isSyncingRef.current = true
store.setState({ files: nextFiles })
isSyncingRef.current = false
}, [value])
return ( return (
<FileContext.Provider value={storeRef.current}> <FileContext.Provider value={storeRef.current}>