fix(plugin-import-export): sync field select dropdown with form value (#13103)

### What?

Fixes a sync issue between the "Fields to Export" `<ReactSelect />`
dropdown and the underlying form state in the import-export plugin.

### Why?

Previously, the dropdown displayed outdated selections until an extra
click occurred. This was caused by an unnecessary `useState`
(`displayedValue`) that fell out of sync with the `useField` form value.

### How?

- Removed the separate `displayedValue` state
- Derived the selected values directly from the form field value using
inline mapping
This commit is contained in:
Patrik
2025-07-09 15:42:06 -04:00
committed by GitHub
parent a7a05012fb
commit 1c6a79bb57

View File

@@ -11,7 +11,7 @@ import {
useField,
usePreferences,
} from '@payloadcms/ui'
import React, { useEffect, useState } from 'react'
import React, { useEffect } from 'react'
import { useImportExport } from '../ImportExportProvider/index.js'
import { reduceFields } from './reduceFields.js'
@@ -25,28 +25,10 @@ export const FieldsToExport: SelectFieldClientComponent = (props) => {
const { getEntityConfig } = useConfig()
const { collection } = useImportExport()
const { getPreference } = usePreferences()
const [displayedValue, setDisplayedValue] = useState<
{ id: string; label: ReactNode; value: string }[]
>([])
const collectionConfig = getEntityConfig({ collectionSlug: collectionSlug ?? collection })
const fieldOptions = reduceFields({ fields: collectionConfig?.fields })
useEffect(() => {
if (value && value.length > 0) {
setDisplayedValue((prevDisplayedValue) => {
if (prevDisplayedValue.length > 0) {
return prevDisplayedValue
} // Prevent unnecessary updates
return value.map((field) => {
const match = fieldOptions.find((option) => option.value === field)
return match ? { ...match, id: field } : { id: field, label: field, value: field }
})
})
}
}, [value, fieldOptions])
useEffect(() => {
if (id || !collectionSlug) {
return
@@ -70,16 +52,18 @@ export const FieldsToExport: SelectFieldClientComponent = (props) => {
id,
collectionConfig?.admin?.defaultColumns,
])
const onChange = (options: { id: string; label: ReactNode; value: string }[]) => {
if (!options) {
setValue([])
return
}
const updatedValue = options?.map((option) =>
const updatedValue = options.map((option) =>
typeof option === 'object' ? option.value : option,
)
setValue(updatedValue)
setDisplayedValue(options)
}
return (
@@ -96,7 +80,14 @@ export const FieldsToExport: SelectFieldClientComponent = (props) => {
// @ts-expect-error react select option
onChange={onChange}
options={fieldOptions}
value={displayedValue}
value={
Array.isArray(value)
? value.map((val) => {
const match = fieldOptions.find((opt) => opt.value === val)
return match ? { ...match, id: val } : { id: val, label: val, value: val }
})
: []
}
/>
</div>
)