programing

Formik과 함께 Material-UI의 자동 완성 구성요소 사용

iphone6s 2023. 3. 28. 21:19
반응형

Formik과 함께 Material-UI의 자동 완성 구성요소 사용

현재 Formik에서 Material UI의 Autocomplete 구성 요소를 사용하려고 합니다.지금까지는 텍스트 필드나 Material-UI의 기존 선택 항목 등이 Formik과 매우 잘 어울립니다.자동완성 구현은 그렇지 않습니다.Formik의 onChange 핸들러가 다음 값을 업데이트하지 않는 것 같습니다.city_idAutocomplete는 아직 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);

angry-goldstine-8offj 편집

너의 문제는 말이다handleChange지금처럼 작동하지 않을 겁니다.

handleChange 문서를 보면 다음과 같습니다.

일반 입력 변경 이벤트 핸들러입니다.그러면 값[키]가 업데이트됩니다.여기서 key는 이벤트 송신 입력의 이름 속성입니다.이름 속성이 없는 경우 handleChange는 입력의 ID 속성을 찾습니다.주의: 여기서 "input"은 모든 HTML 입력을 의미합니다.

잘 될 거예요 하지만 문제는 그 문제가TextField안에서.Autocomplete트리거만 합니다.handleChange그 위에 무언가를 입력하면 값이 텍스트가 됩니다.id아니면 당신이 원하는 다른 재산으로 이사해야 합니다handleChange에게Autocomplete.

그리고 또 다른 문제가 있습니다.handleChange에서Autocomplete왜냐하면 그것은 당신이 원하는 입력을 참조하지 않고 또한 일반과 다른 매개 변수를 가지고 있기 때문이다.onChangeinput를 참조해 주세요.

onChange
기능하다
값이 변경되었을 때 호출되는 콜백.
서명:
function(event: object, value: any) => void
event: 콜백 이벤트소스
value: 특수한 순서

그래서 여러분이 해야 할 일은setFieldValue그리고 그것을 전달하다Autocomplete맘에 들다

onChange={(e, value) => setFieldValue("city_id", value)}

필드의 이름과 원하는 값을 전달해야 합니다.

다음은 작업 예시입니다.

@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"
        />
    )}
/>

사용자가 를 클릭했을 때AutocompleteElement를 기동합니다.onOpen를 실행하고 있습니다.Formik onBlur필드를 터치한 것으로 표시합니다.항목을 선택하지 않으면 Formikflags[ ] 필드 및 [ ]를 표시합니다.Contact is required확인 메시지

를 추가해야 합니다.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도 사용할 수 있습니다.

저는 최근에 같은 문제가 있어서 해결했습니다.경험을 공유하다

에서 값 OnChange 방법

onChange={(event, value) => (formik.values.country = value!)}

여기 전체 코드가 있습니다.

Formik 설정

const formik = useFormik({
    initialValues: {
      id: user.id || "",
      name: user.name || "",
      country: user.country,
      email: user.email || "",
      submit: null,
    },
    validationSchema: Yup.object({
      email: Yup.string()
        .email("Must be a valid email")
        .max(255)
        .required("Email is required"),
      name: Yup.string().max(255).required("Name is required"),
    }),
    onSubmit: async (values, helpers): Promise<void> => {
      console.log("Updating user...");
      try {
        let userData: UserDetails = {
          id: values.id,
          email: values.email,
          name: values.name,
          country: values.country,
        };
        await userApi.registerUser(userData);
        helpers.setStatus({ success: true });
        helpers.setSubmitting(false);
        toast.success("User updated!");
      } catch (err) {
        console.error(err);
        toast.error("Something went wrong!");
        helpers.setStatus({ success: false });
        helpers.setErrors({ submit: err.message });
        helpers.setSubmitting(false);
      }
    },
  });

자동 완성

            <Autocomplete
                getOptionLabel={(option): string => option.text}
                options={countries}
                value={formik.values.country}
                defaultValue={formik.values.country}
                onChange={(event, value) => (formik.values.country = value!)}
                renderInput={(params): JSX.Element => (
                  <TextField
                    {...params}
                    fullWidth
                    label="Country"
                    name="country"
                    error={Boolean(
                      formik.touched.country && formik.errors.country
                    )}
                    helperText={formik.touched.country && formik.errors.country}
                    onBlur={formik.handleBlur}
                  />
                )}
              />

언급URL : https://stackoverflow.com/questions/59217658/using-material-uis-autocomplete-component-with-formik

반응형