Les données sont stockées sous:
{ iso: "gb", label: "United Kingdom", country: "United Kingdom" },
{ iso: "fr", label: "France", country: "France" }
La valeur transmise à la saisie semi-automatique est:
{ iso: "gb", label: "United Kingdom", country: "United Kingdom" }
Erreur signalée dans la console
Material-UI: la valeur fournie à Autocomplete n'est pas valide. Aucune des options ne correspond à
{"label":"United Kingdom","iso":"gb","country":"United Kingdom"}
.
Erreur de type signalée le value={}
Tapez la chaîne | ICountry 'n'est pas attribuable au type' ICountry | ICountry [] | null | indéfini'. Le type "chaîne" ne peut pas être affecté au type "ICountry | ICountry [] | null | indéfini'.
Problème: la transmission de données au composant ne le définit pas sur l'option correspondante, je n'ai plus d'idées sur la façon de résoudre ce problème.
Codesandbox d'émission: https://codesandbox.io/s/charming-firefly-zl3qd?file=/src/App.tsx
import * as React from "react";
import { Box, Typography, TextField, Button } from "@material-ui/core";
import { Autocomplete } from "@material-ui/lab";
import "./styles.css";
import { countries } from "./countries";
import { investors } from "./investor";
import { Formik } from "formik";
interface ICountry {
iso: string;
country: string;
label: string;
}
const isoToFlag = (isoCode: string) => {
if (isoCode) {
return typeof String.fromCodePoint !== "undefined"
? isoCode
.toUpperCase()
.replace(/./g, char =>
String.fromCodePoint(char.charCodeAt(0) + 127397)
)
: isoCode;
}
return "";
};
const App: React.FC = () => {
const investor = investors.find(element => element.id === "123");
return (
<div className="App">
<Formik
initialValues={{
address: {
country: investor?.legal.address.country ? investor.legal.address.country : '',
}
}}
onSubmit={(values, actions) => {
console.log({ values, actions });
actions.setSubmitting(false);
}}
>
{({ submitForm, isSubmitting, values, setFieldValue, setValues }) => {
return (
<form>
<Autocomplete
id="country"
options={countries}
getOptionLabel={option => option.label}
value={values.address.country}
renderOption={(option: ICountry) => (
<Box display="flex" flexDirection="row" alignItems="center">
<Box mr={1}>{isoToFlag(option.iso)}</Box>
<Box>
<Typography variant="body2">{option.label}</Typography>
</Box>
</Box>
)}
onChange={(e: object, value: any | null) => {
console.log('do the types match?', typeof value === typeof values.address.country);
console.log('do the objects match?', value === values.address.country);
console.log('the objects in question', value, values.address.country);
console.log(" ");
setFieldValue("address.country", value);
}}
renderInput={params => (
<TextField
{...params}
name="address.country"
label="Country"
variant="outlined"
fullWidth
/>
)}
/>
<Button
variant="contained"
size="large"
color="primary"
disabled={isSubmitting}
onClick={submitForm}
>
Submit
</Button>
</form>
);
}}
</Formik>
</div>
);
};
export default App;
pays.ts
import { ICountry } from "./investor";
export const countries: ICountry[] = [
{
iso: "gb",
label: "United Kingdom",
country: "United Kingdom"
},
{
iso: "fr",
label: "France",
country: "France"
}
];
Le message complet de Material-UI
est:
Material-UI: la valeur fournie à Autocomplete n'est pas valide. Aucune des options ne correspond à
{"label":"United Kingdom","iso":"gb","country":"United Kingdom"}
. Vous pouvez utiliser le propgetOptionSelected
pour personnaliser le test d'égalité.
Le test d'égalité par défaut est simplement ===
, donc si vos options sont des objets, votre valeur devra être l'un de ces objets exacts pour correspondre. Un objet différent avec les mêmes valeurs ne correspondra pas.
Mais comme le message vous l'indique, vous pouvez personnaliser le test d'égalité via la propriété getOptionSelected
. Par exemple, vous pouvez spécifier:
getOptionSelected={(option, value) => option.iso === value.iso}
ou vous pouvez effectuer une vérification d'égalité approfondie de toutes les propriétés de l'objet.
L'erreur de type peut être corrigée avec value={values.address.country as ICountry}
.
Voici une version fonctionnelle de votre sandbox: https://codesandbox.io/s/autocomplete-getoptionselected-b6n3s