現在、FormikでMaterial UIの Autocomplete コンポーネントを使用しようとしています。これまでのところ、テキストフィールドやMaterial-UIからの従来の選択などは、Formikで非常にうまく機能します。オートコンプリートの実装はそうではありません。 FormikのonChangeハンドラーがcity_id
の値を更新していないようです。私はオートコンプリートがまだMaterial-UIのコアライブラリの一部ではないことを知っていますが、現時点でこのようなことが可能であるかどうかを確認していました。
import React from "react";
import ReactDOM from "react-dom";
import { Formik, Form } from 'formik';
import TextField from '@material-ui/core/TextField';
import Autocomplete from '@material-ui/lab/Autocomplete';
import Button from '@material-ui/core/Button';
import { cities } from '../data/cities';
import "./styles.css";
const initialValues = {
city_id: '',
};
const submit = params => {
alert(`Value for city_id is: ${params.city_id}`);
};
function App() {
return (
<Formik
initialValues={ initialValues }
onSubmit={ submit }
>
{({
handleChange,
values,
}) => (
<Form>
<Autocomplete
id="city_id"
name="city_id"
options={ cities }
groupBy={ option => option.state }
getOptionLabel={ option => option.name }
style={{ width: 300 }}
renderInput={params => (
<TextField
{ ...params }
onChange={ handleChange }
margin="normal"
label="Cities"
fullWidth
value={ values.city_id }
/>
)}
/>
<Button
variant="contained"
color="primary"
type="submit"
>
Submit
</Button>
</Form>
)}
</Formik>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
あなたの問題は、handleChange
があなたがしているように機能しないことです。
handleChange docs を見てみると:
一般的な入力変更イベントハンドラ。これにより、values [key]が更新されます。ここで、keyはイベントを発行する入力の名前属性です。 name属性が存在しない場合、handleChangeは入力のid属性を探します。注:ここでの「入力」とは、すべてのHTML入力を意味します。
正常に動作するはずですが、問題は、TextField
内のAutocomplete
が何かを入力したときにのみhandleChange
をトリガーし、値はテキストであり、 id
またはその他の必要なプロパティなので、handleChange
をAutocomplete
に移動する必要があります。
そして、もう1つの問題があります。handleChange
でAutocomplete
を使用することはできません。これは、必要な入力を参照せず、通常のonChange
とは異なるパラメーターも持っているためです。 docs で確認できるように、input
の.
onChange
機能
値が変更されたときに呼び出されるコールバック。
署名:function(event: object, value: any) => void
event
:コールバックのイベントソースvalue
:null
だからあなたがする必要があるのはsetFieldValue
を使ってAutocomplete
に渡すことです
onChange={(e, value) => setFieldValue("city_id", value)}
フィールドの名前と取得したい値を渡す必要があります。
これが 動作例 です
@vencovskyが正解を提供してくれましたが、Material UI 14.10.1でまだ機能しています。
required
検証を使用してフィールドをYup
に設定しているので、もう少し追加しています。
これを正しく動作させるには、次のようにします。Yup
config:
validationSchema = {
Yup.object().shape({
contact: Yup.string().max(255).required('Contact is required'),
})
}
反応:
<Autocomplete
id="contact-autocomplete"
options={contacts}
getOptionLabel={(contact) => `${contact?.firstName} ${contact?.lastName}`}
onChange={(e, value) => setFieldValue("contact", value?.id || "")}
onOpen={handleBlur}
includeInputInList
renderInput={(params) => (
<TextField
{...params}
error={Boolean(touched.contact && errors.contact)}
fullWidth
helperText={touched.contact && errors.contact}
label="Contact Person"
name="contact"
variant="outlined"
/>
)}
/>
ユーザーがAutocomplete
要素をクリックすると、onOpen
を起動してFormik
onBlur
を実行し、フィールドにタッチ済みのマークを付けます。アイテムが選択されない場合、Formik flags
フィールドを表示してContact is required
検証メッセージ。