fix: update select options when the options prop changes (#6878)

Fixes https://github.com/payloadcms/payload/issues/6869

Before, options from props were being stored in state and would not
update when props changed. Now options are memoized and will update when
the incoming `options` prop changes.
This commit is contained in:
Jarrod Flesch
2024-06-20 12:01:29 -04:00
committed by GitHub
parent 6ba619f6f4
commit 8773e3a7e5
6 changed files with 83 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
'use client'
import type { Option } from 'payload'
import { SelectField, useField } from '@payloadcms/ui'
import React from 'react'
export const CustomSelect = ({ path }: { path: string }) => {
const { setValue, value } = useField<string>({ path })
const [options, setOptions] = React.useState<{ label: string; value: string }[]>([])
React.useEffect(() => {
const fetchOptions = () => {
const fetchedOptions = [
{
label: 'Label 1',
value: 'value1',
},
{
label: 'Label 2',
value: 'value2',
},
]
setOptions(fetchedOptions)
}
void fetchOptions()
}, [])
const onChange = (selected: Option | Option[]) => {
const options = Array.isArray(selected) ? selected : [selected]
setValue(options.map((option) => (typeof option === 'string' ? option : option.value)))
}
return (
<div>
<SelectField
hasMany
name={path}
onChange={onChange}
options={options}
path={path}
value={value}
/>
</div>
)
}

View File

@@ -0,0 +1,19 @@
import type { CollectionConfig } from 'payload'
import { customFieldsSlug } from '../../slugs.js'
import { CustomSelect } from './components/CustomSelect.js'
export const CustomFields: CollectionConfig = {
slug: customFieldsSlug,
fields: [
{
name: 'customSelectField',
type: 'text',
admin: {
components: {
Field: CustomSelect,
},
},
},
],
}

View File

@@ -3,6 +3,7 @@ import path from 'path'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
import { CustomFields } from './collections/CustomFields/index.js'
import { CustomIdRow } from './collections/CustomIdRow.js'
import { CustomIdTab } from './collections/CustomIdTab.js'
import { CustomViews1 } from './collections/CustomViews1.js'
@@ -116,6 +117,7 @@ export default buildConfigWithDefaults({
CollectionNoApiView,
CustomViews1,
CustomViews2,
CustomFields,
CollectionGroup1A,
CollectionGroup1B,
CollectionGroup2A,

View File

@@ -34,6 +34,7 @@ import {
slugPluralLabel,
} from '../../shared.js'
import {
customFieldsSlug,
customIdCollectionId,
customViews2CollectionSlug,
disableDuplicateSlug,
@@ -70,6 +71,7 @@ describe('admin1', () => {
let postsUrl: AdminUrlUtil
let globalURL: AdminUrlUtil
let customViewsURL: AdminUrlUtil
let customFieldsURL: AdminUrlUtil
let disableDuplicateURL: AdminUrlUtil
let serverURL: string
let adminRoutes: ReturnType<typeof getAdminRoutes>
@@ -89,6 +91,7 @@ describe('admin1', () => {
postsUrl = new AdminUrlUtil(serverURL, postsCollectionSlug)
globalURL = new AdminUrlUtil(serverURL, globalSlug)
customViewsURL = new AdminUrlUtil(serverURL, customViews2CollectionSlug)
customFieldsURL = new AdminUrlUtil(serverURL, customFieldsSlug)
disableDuplicateURL = new AdminUrlUtil(serverURL, disableDuplicateSlug)
const context = await browser.newContext()
@@ -481,6 +484,16 @@ describe('admin1', () => {
})
})
describe('custom fields', () => {
describe('select field', () => {
test('should render custom select options', async () => {
await page.goto(customFieldsURL.create)
await page.locator('#field-customSelectField .rs__control').click()
await expect(page.locator('#field-customSelectField .rs__option')).toHaveCount(2)
})
})
})
describe('API view', () => {
test('collection — should not show API tab when disabled in config', async () => {
await page.goto(postsUrl.collection(noApiViewCollectionSlug))

View File

@@ -11,6 +11,7 @@ export const hiddenCollectionSlug = 'hidden-collection'
export const noApiViewCollectionSlug = 'collection-no-api-view'
export const disableDuplicateSlug = 'disable-duplicate'
export const uploadCollectionSlug = 'uploads'
export const customFieldsSlug = 'custom-fields'
export const collectionSlugs = [
usersCollectionSlug,
customViews1CollectionSlug,
@@ -23,6 +24,7 @@ export const collectionSlugs = [
group2Collection2Slug,
hiddenCollectionSlug,
noApiViewCollectionSlug,
customFieldsSlug,
disableDuplicateSlug,
]