Reactjs 使用材料界面';用Formik自动完成组件

Reactjs 使用材料界面';用Formik自动完成组件,reactjs,material-ui,formik,Reactjs,Material Ui,Formik,目前正在尝试将Material UI的组件与Formik一起使用。到目前为止,文本字段和从材质UI中选择的传统内容都可以很好地使用Formik。实现自动完成并非如此。Formik的onChange处理程序似乎没有更新mycity\u id的值。我知道Autocomplete仍然不是MaterialUI的核心库的一部分,但目前仍在考虑这样的可能性 import React from "react"; import ReactDOM from "react-dom"; import { Formik

目前正在尝试将Material UI的组件与Formik一起使用。到目前为止,文本字段和从材质UI中选择的传统内容都可以很好地使用Formik。实现自动完成并非如此。Formik的onChange处理程序似乎没有更新my
city\u id的值。我知道Autocomplete仍然不是MaterialUI的核心库的一部分,但目前仍在考虑这样的可能性

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);
从“React”导入React;
从“react dom”导入react dom;
从'Formik'导入{Formik,Form};
从“@material ui/core/TextField”导入TextField;
从“@material ui/lab/Autocomplete”导入自动完成;
从“@material ui/core/Button”导入按钮;
从“../data/cities”导入{cities};
导入“/styles.css”;
常量初始值={
城市id:“”,
};
const submit=params=>{
警报(`city_id的值为:${params.city_id}`);
};
函数App(){
返回(
{({
handleChange,
价值观
}) => (

您的问题是
handleChange
无法按您现在的方式工作

如果您查看以下内容:

常规输入更改事件处理程序。这将更新值[key],其中key是发出事件的输入的name属性。如果name属性不存在,handleChange将查找输入的id属性。注意:“input”在这里表示所有HTML输入

这应该可以正常工作,但问题是
Autocomplete
中的
TextField
只会在您键入内容时触发
handleChange
,值将是文本,而不是
id
或您想要的其他属性,因此您需要将
handleChange
移动到
Autocomplete

还有一个问题,您不能在
自动完成
中使用
handleChange
,因为它没有引用您想要的输入,而且它的参数也与
输入
的正常
onChange
不同,如您在中所见

onChange

func
值更改时触发回调。
签名:
函数(事件:对象,值:任意)=>void

event
:回调的事件源
:空

因此,您需要做的是使用
setFieldValue
并将其传递给
Autocomplete
like

onChange={(e, value) => setFieldValue("city_id", value)}
您需要传递字段的名称以及希望获得的值


下面是一个

@vencovsky提供的正确答案,它仍然适用于我的UI 14.10.1材料

在使用
Yup
validation时,我将字段设置为
required
,因此我添加了更多内容

要使其正常工作,我有以下几点:
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"
        />
    )}
/>
`${contact?.firstName}${contact?.lastName}`}
onChange={(e,value)=>setFieldValue(“contact”,value?.id | |“”)}
onOpen={handleBlur}
includeInputList
renderInput={(参数)=>(
)}
/>

当用户单击
Autocomplete
元素时,它会启动
onOpen
,运行
Formik
onBlur
并将字段标记为已触摸。如果随后未拾取项目,则Formik
会标记该字段,并显示
联系人是必需的
验证消息。

您必须添加
>onChange={(事件,值)=>handleChange(值)}
in
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);
从“React”导入React;
从“react dom”导入react dom;
从'Formik'导入{Formik,Form};
从“@material ui/core/TextField”导入TextField;
从“@material ui/lab/Autocomplete”导入自动完成;
从“@material ui/core/Button”导入按钮;
从“../data/cities”导入{cities};
导入“/styles.css”;
const[cityId,setCityId]=React.useState({city_id:''});
常量handleChange=(值)=>{
//以下是所选选项标签的值或新键入的值
setCityId({city_id:value});
}
函数App(){
返回(
{
警报(`city_id的值为:${cityId.city_id}`);
}}
>
{({
handleChange,
价值观
}) => (
option.state}
getOptionLabel={option=>option.name}
样式={{宽度:300}
onChange={(事件,值)=>handleChange(值)}
renderInput={params=>(
)}
/>
提交
)}
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);

<> P> <强>如果不工作,也可以使用OnnPosichange。< St/强>

完美!谢谢您!欢迎您考虑,谢谢!为彻底解释做了!也请考虑我的问题,如果它被认为是值得注意的。作为补充,材料4.7中的自动完成组件有8个补丁。1因此,如果有人在遵循文科夫斯基的解释后仍然存在问题,这可能就是原因。