当前尝试在Formik中使用Material UI的Autocomplete组件。到目前为止,Formik可以很好地处理文本字段和Material-UI中的传统选择之类的事情。并非如此。 Formik的onChange处理程序似乎并未更新我的city_id
的值。我知道Autocomplete仍然不是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);
答案 0 :(得分:3)
您的问题是handleChange
无法按照您的方式工作。
如果您看看handleChange docs:
常规输入更改事件处理程序。这将更新values [key],其中key是发出事件的输入的name属性。如果不存在name属性,则handleChange将查找输入的id属性。注意:“输入”在这里表示所有HTML输入。
应该可以正常工作,但问题是TextField
中的Autocomplete
仅在您键入内容时会触发handleChange
,并且值将是文本,而不是id
或其他所需属性,因此您需要将handleChange
移至Autocomplete
。
还有一个问题,您不能在handleChange
中使用Autocomplete
,因为它没有引用您想要的输入,并且它的参数与普通的onChange
不同docs中可以看到input
中的一个。
onChange
func
值更改时触发回调。
签名:
function(event: object, value: any) => void
event
:回调的事件源
value
:null
所以您需要做的是使用setFieldValue
并将其像
Autocomplete
onChange={(e, value) => setFieldValue("city_id", value)}
您需要传递字段名称和想要获取的值。
答案 1 :(得分:2)
@vencovsky提供了正确的答案,该答案仍适用于Material UI 14.10.1。
。由于要在使用required
验证的情况下将字段设置为Yup
,因此要添加更多内容。
要使其正常工作,我需要执行以下操作:
Yup
配置:
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
验证消息。
答案 2 :(得分:0)
您必须在onChange = {(event, value) => handleChange(value)}
标签中将Autocomplete
添加为
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 [cityId,setCityId]=React.useState({city_id:''});
const handleChange=(value)=>{
// Here is the value is a selected option label or the new typed value
setCityId({city_id:value});
}
function App() {
return (
<Formik
initialValues={ cityId }
onSubmit={() => {
alert(`Value for city_id is: ${cityId.city_id}`);
}}
>
{({
handleChange,
values,
}) => (
<Form>
<Autocomplete
id="city_id"
name="city_id"
options={ cities }
groupBy={ option => option.state }
getOptionLabel={ option => option.name }
style={{ width: 300 }}
onChange = {(event, value) => handleChange(value)}
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);
如果onChange不起作用,您也可以使用onInputChange。