Formik: material ui select in formik

Created on 14 Dec 2019  路  3Comments  路  Source: formium/formik

鉂換uestion

I am using formik and material ui in react project.when I use material ui select,and click on submit button.show me validation error required under select field. I use yhese codes.

import React from 'react';
import {useFormik} from 'formik';
import * as Yup from 'yup';
import {makeStyles} from '@material-ui/core/styles';
import InputLabel from '@material-ui/core/InputLabel';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import Button from "@material-ui/core/Button";
import Grid from "@material-ui/core/Grid";
import TextField from "@material-ui/core/TextField";

const useStyles = makeStyles(theme => ({
    formControl: {
        minWidth: 120,
    },
    selectEmpty: {
        marginTop: theme.spacing(2),
    },
    form: {
        display: "flex",
        flexDirection: 'column'
    },
    formContainer: {
        display: 'flex',
        justifyContent: 'center'
    },
    submitButton: {
        width: '90px',
        height: '50px'
    }
}));


const ProfileForm = (props) => {
    const classes = useStyles();
    const [handle, setHandle] = React.useState('');
    const handleSelect = event => {
        setHandle(event.target.value);
    };
    const formik = useFormik({
        initialValues: {
            handle: '',
            company: '',
            website: '',
            location: "", bio: "", status: "",skills:""
        },
        validationSchema: Yup.object({
            handle: Yup.string()
                .required('Required'),
            company: Yup.string()
                .required('Required'),
            website: Yup.string()
                .required('Required'),
            location: Yup.string()
                .required('Required'),
            bio: Yup.string()
                .required('Required'),
            status: Yup.string()
                .required('Required'),
            skills: Yup.string()
                .required('Required'),
        }),
        onSubmit: values => {
            console.log(values)
            props.onSubmitPro(values)
        },
    });
    const {
        values,
        touched,
        errors,
        handleChange,
        handleBlur,
        handleSubmit
    } = formik;
    return (
        <div>
            <Grid container spacing={3} className={classes.formContainer}>
                <Grid item xs={12} sm={10} md={6} >

                    <form onSubmit={handleSubmit} className={classes.form}>

                        <FormControl className={classes.formControl}>
                            <InputLabel id="handle">Handle</InputLabel>
                            <Select
                                labelId="handle"
                                id="handle"
                                value={handle}
                                onChange={handleSelect}
                            >
                                <MenuItem value="">
                                    <em>None</em>
                                </MenuItem>
                                <MenuItem value="Ten">Ten</MenuItem>
                                <MenuItem value="Twenty">Twenty</MenuItem>
                                <MenuItem value="Thirty">Thirty</MenuItem>
                            </Select>
                            <FormHelperText>{(errors.company && touched.company) && errors.company}</FormHelperText>
                        </FormControl>
                        <TextField required id="company" label="Company"
                                   name="company"
                                   value={values.company}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.company && touched.company) && errors.company}
                                   margin="normal"
                        />
                        <TextField required id="website" label="Website"
                                   name="website"
                                   value={values.website}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.website && touched.website) && errors.website}
                                   margin="normal"
                        />

                        <TextField required id="location" label="Location"
                                   name="location"
                                   value={values.location}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.location && touched.location) && errors.location}
                                   margin="normal"
                        />
                        <TextField required id="bio" label="Bio"
                                   name="bio"
                                   value={values.bio}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.bio && touched.bio) && errors.bio}
                                   margin="normal"
                        />

                        <TextField required id="status" label="Status"
                                   name="status"
                                   value={values.status}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.status && touched.status) && errors.status}
                                   margin="normal"
                        />

                        <TextField required id="skills" label="Skills"
                                   name="skills"
                                   value={values.skills}
                                   onChange={handleChange}
                                   onBlur={handleBlur}
                                   helperText={(errors.skills && touched.skills) && errors.skills}
                                   margin="normal"
                        />

                        <Button type="submit" color="primary" variant="contained"
                                className={classes.submitButton}>Submit</Button>
                    </form>
                </Grid>
            </Grid>
        </div>
    );
};
export default ProfileForm;

how can I solve this problem?

Support Redirect Question

Most helpful comment

I had more luck after changing to this style:

    <Grid>
        <TextField
            id="state"
            select
            label="State"
            className={classes.textField}
            value={values.state}
            onChange={handleChange("state")}
            margin="normal"
            fullWidth
            >
            <MenuItem value="">
                <em>None</em>
            </MenuItem>
            {usStates?.states.map(state => (
                <MenuItem key={state.abbreviation} value={state.abbreviation}>
                    {state.name}
                </MenuItem>
            ))}
        </TextField>
    </Grid>

All 3 comments

Why was this closed without a solution?

The user above has overwritten onChange. Instead of passing Formik's handleChange event handler, they're passing a custom state setter. Thus, formik.values.mySelect will never be valid.

Pass formik.handleChange to Select's onChange and everything should work fine. May need to pass handleChange(fieldName) if Material Select's onChange passes a value and not a change event.

I had more luck after changing to this style:

    <Grid>
        <TextField
            id="state"
            select
            label="State"
            className={classes.textField}
            value={values.state}
            onChange={handleChange("state")}
            margin="normal"
            fullWidth
            >
            <MenuItem value="">
                <em>None</em>
            </MenuItem>
            {usStates?.states.map(state => (
                <MenuItem key={state.abbreviation} value={state.abbreviation}>
                    {state.name}
                </MenuItem>
            ))}
        </TextField>
    </Grid>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sibelius picture sibelius  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

pmonty picture pmonty  路  3Comments

dearcodes picture dearcodes  路  3Comments

jeffbski picture jeffbski  路  3Comments