问题
I have a countries
array which contains id
and name
. Currently I am using a Material UI Autocomplete
element and I have a react hook form. When I submit the form, I want to fetch the the country Id. Currently it is posting the country name. Is there a way to post the ids instead of the names without going and fetching the id from the name.
<Autocomplete
className="form-item"
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
inputRef={register}
label="Country"
name="country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
回答1:
I'm afraid that there is not an 'easy' way to get the ids with the current setup.
However, you can hook into the Autocomplete#onChange
event and use the value
prop to take over the internal value state of the Autocomplete component. This results in having the value available in your component and use this to your advantage.
In the example below, the id will be available in the form data as country-id
.
function CountryAutocomplete() {
const [value, setValue] = useState(); // `[]` for multiple
return (
<React.Fragment>
<Autocomplete
className="form-item"
value={value}
onChange={(event, value) => setValue(value)}
options={countries}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField
{...params}
inputRef={register}
label="Country"
name="country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
<input value={value?.id} name="country-id" />
</React.Fragment>
);
}
回答2:
Use react-hook-form's Controller and put the entire Autocomplete
in the as
prop. With this, when you submit the form you will get the entire object of the selected option.
Note: In react-hook-form version 6.x, the onChange
is removed, the as prop will take a function and you can obtain onChange
as param.
Working demo - v6
<Controller
as={({ onChange }) => (
<Autocomplete
className="form-item"
options={countries}
onChange={(_, data) => onChange(data)}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField
{...params}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
)}
name="country"
control={control}
defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
/>
Note: If you are using v5x then see demo and code snippet below.
Working demo - v5
<Controller
as={
<Autocomplete
className="form-item"
options={countries}
getOptionLabel={option => option.label}
renderInput={params => (
<TextField
{...params}
label="Country"
placeholder="Select a Country"
InputLabelProps={{
shrink: true
}}
variant="outlined"
/>
)}
/>
}
name="country"
control={control}
onChange={([, data]) => data}
defaultValue={{ label: "The Shawshank Redemption", id: "1994" }}
/>
Edit: based on comment You can use setValue to set default values based on an api.
code snippet:
useEffect(() => {
setTimeout(() => { // fake api
setValue(
"country",
{ label: "hi The Godfather", id: "1972" },
{ shouldDirty: true }
);
}, 2000);
}, []);
Demo v6 above is updated.
Also see official demo of setValue usage here
来源:https://stackoverflow.com/questions/62997374/react-form-hook-with-autocomplete-material-ui