I am trying to initialize a dynamic list of User with a DropDown from the PrimeReact library. I am able to load it, even though I am not sure if it is the right way. I am able to select a User, but unable to pass it down to the form. I am also not sure I am supposed to select the User without a state. I am a bit confused on how those interact between each other. It would be really helpful if I could have a bit of guidance.
import { useState, useEffect, useContext } from 'react'
import { Form, Field } from 'react-final-form'
import { Panel } from 'primereact/panel'
import { Dropdown, DropdownProps } from 'primereact/dropdown'
import { Button } from 'primereact/button'
import { api } from '../services' //Axios instance
export interface IUser {
id: number
firstName: string
lastName: string
}
const selectedUserItemTemplate = (option: IUser) => {
return <span>{`${option.lastName} ${option.firstName}`}</span>
}
const selectedUserValueTemplate = (
option: IUser,
{ placeholder }: DropdownProps
) => {
return option ? (
<span>{`${option.lastName} ${option.firstName}`}</span>
) : (
<span>{placeholder}</span>
)
}
const DropDownAdaptater = ({ input, meta, hintText, data, ...rest }: any) => {
const [selectedUser, setSelectedUser] = useState(undefined)
const [users, setUsers] = useState<IUser[]>([])
useEffect(() => {
const fetchUsers = async () => {
const { data } = await api.get<IUser[]>('/users')
setUsers(data)
}
fetchUsers()
}, [])
console.log(input.value) //Empty -> the form does not update
return (
<Dropdown
{...input}
value={selectedUser}
options={users}
onChange={(e) => setSelectedUser(e.target.value)}
itemTemplate={selectedUserItemTemplate}
valueTemplate={selectedUserValueTemplate}
optionLabel="optionLabel"
placeholder={hintText}
style={{ marginRight: '1rem', width: '240px' }}
/>
)
}
export const Login: React.FC = () => {
const onSubmitAuthForm = () => {
console.log('submit')
}
return (
<Panel header="Login">
<Form onSubmit={onSubmitAuthForm}>
{({ handleSubmit, form, submitting, pristine, values }) => {
console.log('values FORM', values) // -----> Empty
return (
<form onSubmit={handleSubmit}>
<h5>Select a user</h5>
<Field
name="userName"
component={DropDownAdaptater}
hintText="Select a user"
/>
<Button label="Login" />
</form>
)
}}
</Form>
</Panel>
)
}
Try updating the value your self.
See here is an example for the same
const DropDownAdaptater = ({ input, meta, hintText, data, ...rest }: any) => {
const [selectedUser, setSelectedUser] = useState(undefined)
const [users, setUsers] = useState<IUser[]>([])
useEffect(() => {
const fetchUsers = async () => {
const { data } = await api.get<IUser[]>('/users')
setUsers(data)
}
fetchUsers()
}, [])
useEffect(()=>{
// update the input value, when selected
// note: it must be a single value and not an object
input.value= selectedUser.userName;
},[selectedUser])
return (
<Dropdown
{...input}
value={selectedUser}
options={users}
onChange={(e) => setSelectedUser(e.target.value)}
itemTemplate={selectedUserItemTemplate}
valueTemplate={selectedUserValueTemplate}
optionLabel="optionLabel"
placeholder={hintText}
style={{ marginRight: '1rem', width: '240px' }}
/>
)
}