简体   繁体   中英

Passing a 'label' prop into Formik <Field /> when using alongside Material UI <TextField />

I'm building a form using Formik and Material UI.

I'm leveraging the Formik component the following way:

My Input component:

const Input = ({ field, form: { errors } }) => {
  const errorMessage = getIn(errors, field.name);
  return <TextField {...field} />;
};

And down into my rendered form, here's how I do it:

<Field
  component={Input}
  name={`patients[${index}].firstName`}
/>

The problem is that Material UI uses a label prop to display label on an input field so the label should be a prop passed to. It works if I "hard-code" it into my "Input" component which defeats the purpose of using a reusable comp.

So that works but inconvenient:

const Input = ({ field, form: { errors } }) => {
  console.log(field.label);
  const errorMessage = getIn(errors, field.name);
  return <TextField {...field} label="first name" />;
};

What I hoped for was using it one level above such as:

<Field
  component={Input}
  name={`patients[${index}].firstName`}
  label="first name"
/>

but the above doesn't work as "label" is not recognised as a prop by Formik (or that's how I understand it but I might be wrong).

Has anyone come across that issue?

I know I could use my "name" value as a label but it's not great UX as it would leave me with a label such as "patients[0].firstName" aha

Here is a good solution, that is essentially yours, but you can provide anything, not only label. Create the field and put the label on the like so:

<Field name={`patients[${index}].firstName`} label='First Name' component={MuiTextFieldFormik} />

The trick is to use the spread operator, then the custom component becomes:

import React from 'react';
import { TextField } from "@material-ui/core"
import { get } from "lodash"

export const MuiTextFieldFormik = ({ field, form: { touched, errors }, ...props }) => {
  const error = get(touched, field.name) && !!get(errors, field.name)
  const helperText = get(touched, field.name) && get(errors, field.name)

  return (
    <TextField fullWidth variant="outlined" {...field} {...props} error={error} helperText={helperText} />
  )
}

disappointing that their docs do not have such simple example

Ok so I think I found the solution. The way I was destructing my arguments, I was only passing field and form which are holding most of the data from so passing a label prop this way fixes that:

const Input = ({ field, label, form: { errors } }) => {
  const errorMessage = getIn(errors, field.name);
  return <TextField {...field} label={label} />;
};

Then when I use the Formik component this way, the correct label gets passed:

<Field
  label="first name"
  component={Input}
  name={`patients[${index}].firstName`}
/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM