Hello! I'm just starting out with Payload 3.0 Beta, and I am wondering how I can pull some product list from an external API and allow users to select a "Featured Product" within the CMS and grab that product's data after. How can I setup something like this in Payload 3?
Sorry for not providing any code, but you can create a custom field in which you can then build your own component, fetch and set the data to the field.
This is a good start:
https://www.youtube.com/watch?v=Efn9OxSjA6YRelated docs:
[Swap in your own React components](
https://payloadcms.com/docs/beta/admin/components)
[React Hooks](
https://payloadcms.com/docs/beta/admin/hooks)
Oh! That's exactly what I was looking for, thank you!
Follow up, the updated admin Field property wants a CustomComponent, and a normal component does not seem to do the job. Any examples that show how to do this?
Oh, the error is:
Type '({ path }: { path: any; }) => Element' is not assignable to type 'CustomComponent & (CustomComponent | undefined)'I did find "SelectFieldDescriptionServerComponent" and "SelectFieldLabelServerComponent" types but obviosuly they won't work for:
const ProductSelect = ({ path }) => {
const { value, setValue } = useField<string>({ path })
const [options, setOptions] = useState([])
useEffect(() => {
const fetchOptions = async () => {
const response = await fetch('')
}
})
return (
<div>
<label className="field-label">Product Select</label>
<SelectInput
path={path}
name={path}
options={options}
value={value}
onChange={(e) => setValue(e.value)}
/>
</div>
)
}That's how it was usually done, now there's nothing passed down to the component AFAIK and you can type it as a simple React.FC component, so you'll need to use [React Hooks](
https://payloadcms.com/docs/beta/admin/hooks).
pathcan be also found there 🙂:
const { value, setValue, path } = useField()Gotcha. Then is it fine to ignore the error in my config on my collection that's accessing my custom component?
Type 'FC' is not assignable to type 'CustomComponent & (CustomComponent | undefined)Can you show an example of your field confing and how you're setting up the component?
But after beta.79 you can't pass in React components anyway, just string of the path:
Oh I was passing in a component as the video was showing, I'll switch that over to a string then, thanks!
Before that I think you'll have to type it as a CustomComponent, at least that's how I did it 😁 but yeah, some things have changed in the beta
{
name: 'productSelect',
type: 'text',
admin: {
components: {
Field: ProductSelect,
},
},
},That's what I had ^^^
I see, so if you're using newer version than beta.79, you'll simply need a string
Sweet! That's easy! Hopefully my last question haha
My
useField()function wants a default value, and if I'm not grabbing any props, what Options value do I provide it?
Can you share code? For me, I don't even need any path and I can pass an empty object to
useField. Here's a custom component I have:
'use client'
import React from 'react'
import { useField } from '@payloadcms/ui'
import './index.scss'
export const StatusSelectField: React.FC = () => {
const { value, setValue } = useField({})
const toggleStatus = () => {
switch (value) {
case 'published':
setValue('expired')
break
case 'expired':
setValue('unpublished')
break
case 'unpublished':
default:
setValue('published')
break
}
}
const getStatusText = () => {
switch (value) {
case 'published':
return 'Published'
case 'expired':
return 'Expired'
case 'unpublished':
default:
return 'Not Published'
}
}
return (
<div className={`status-select-field ${value}`} onClick={toggleStatus}>
<p className="status-text">{`${getStatusText()}. Click to change.`}</p>
</div>
)
}Well passing in an empty object worked!
const ProductSelect: FC = () => {
const { path: pathDefault } = useFieldProps()
const { value, setValue, path } = useField<string>({})
const [options, setOptions] = useState([])
useEffect(() => {
const fetchOptions = async () => {
const response = await fetch('')
}
})
return (
<div>
<label className="field-label">Product Select</label>
<SelectInput
label="Product Select"
path={path}
name={path}
options={options}
value={value}
onChange={(e) => setValue(e.value)}
/>
</div>
)
}Star
Discord
online
Get dedicated engineering support directly from the Payload team.