user image

nico
Published in : 2022-02-14

How to use Datepick of Mui with Formik

React js

When we select a data we get the error please see the codesandbox below

Cannot read properties of undefined (reading 'type')

Expected behavior

we must be able to select a date

Reproducible example

See

https://codesandbox.io/s/formik-codesandbox-template-forked-xonzi?file=/index.js

Your environment

"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@material-ui/core": "^4.12.3",
"@material-ui/lab": "^4.0.0-alpha.60",
"@mui/lab": "^5.0.0-alpha.68",
"@mui/material": "^5.4.1",
"@mui/x-data-grid": "^5.5.0",
"axios": "^0.25.0",
"bootstrap": "^4.6.1",
"date-fns": "^2.28.0",
"formik": "^2.2.9",
"jquery": "^3.6.0",
"material-ui-search-bar": "^1.0.0",
"merge": "^2.1.1",
"oidc-client": "^1.11.5",
"react": "^16.0.0",
"react-bootstrap": "^2.1.2",
"react-dom": "^16.0.0",
"react-loader-spinner": "^5.1.0",
"react-redux": "^7.2.6",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.1.2",
"react-sortable-tree": "^2.8.0",
"reactstrap": "^8.4.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.4.1",
"rimraf": "^2.6.2",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^2.1.1",
"uuid": "^8.3.2"

Comments

Mohamed Atef Date : 2022-02-14

Best answers

46

Best answers

46

Hello Nico, Thank you for using Web-Brackets.com, you are using a different way to get the data onChange so the function which called  formik.handleChange doesn't work because somehow the event does not pass to handleChange so you do it in this way 

<DatePicker
   label="Departure Date"
   id="departureDate"
   name="departureDate"
   value={formik.values.departureDate}
   onChange={(val) => {
        console.log(val);
        //val is the variable which contain the selected date
        //You can set it anywhere
   }}
   renderInput={(params) => <TextField {...params} />}
/>

so the full code should looks like 

import React from "react";
import { render } from "react-dom";
import { useFormik } from "formik";

import TextField from "@mui/material/TextField";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import DatePicker from "@mui/lab/DatePicker";

import "./style.css";

export function App() {
  // A custom validation function. This must return an object
  // which keys are symmetrical to our values/initialValues
  const validate = (values) => {
    const errors = {};

    return errors;
  };

  const formik = useFormik({
    initialValues: {
      departureDate: Date.now()
    },
    validate,
    onSubmit: (values) => {
      alert(JSON.stringify(values, null, 2));
    }
  });

  return (
    <div style={{ height: 400, width: "100%" }}>
      <form>
        <div className="form-group row">
          <label for="departureDate" className="col-sm-7 col-form-label">
            Departure Date
          </label>
          <div className="col-sm-5">
            <LocalizationProvider dateAdapter={AdapterDateFns}>
              <DatePicker
                label="Departure Date"
                id="departureDate"
                name="departureDate"
                value={formik.values.departureDate}
                onChange={(val) => {
                    console.log(val);
                    //val is the variable which contain the selected date
                    //You can set it anywhere
                }}
                renderInput={(params) => <TextField {...params} />}
              />
            </LocalizationProvider>
            {formik.errors.departureDate ? (
              <div>{formik.errors.departureDate}</div>
            ) : null}
          </div>
        </div>
      </form>
    </div>
  );
}

render(<App />, document.getElementById("root"));

this will not make an error when you select a date but the point is setting the value to the form you can do it using a function called setFieldValue and it should be use like this 

<LocalizationProvider dateAdapter={AdapterDateFns}>
  <DatePicker
    label="Departure Date"
    id="departureDate"
    name="departureDate"
    value={formik.values.departureDate}
    onChange={(val) => {
        //val is the variable which contain the selected date
        //You can set it anywhere
        formik.setFieldValue('departureDate', val);
    }}
    renderInput={(params) => <TextField {...params} />}
  />
</LocalizationProvider>
{formik.errors.departureDate ? (
  <div>{formik.errors.departureDate}</div>
) : null}
{console.log(formik.values.departureDate)}

Good luck

nico Date : 2022-02-14

Best answers

4

Best answers

4

Thanks Mohamed for your kind help, I resolved the problem meanwhile and used the solution you adviced.
Your answer confirms that I took the right direction ! :)

The forum is good ! I posted my question to the github of formik and also of mui, no answer all day long, seems to be dead or dead slow…

To remind the full context

My code didn't work first because 

  • the DateTime picker doesn't set the same type of data as in the initialValues.
  • DateTime picker sends an object containing a property which is the date time in full string format.

so to fully resolve my problem i did use the same solution you advise:

  1. in the onChange, we can use the formik object to trigger the SetFieldValue so we can correct the value sent to formik
  2. Date.parse will be used so we can send to formik the same data type as in the initial value : number of milliseconds elapsed since January 1, 1970 00:00:00 UTC like the Date.now() used to initialise the departureDate
     

Date.parse(value) is the number of ms of the date selected, Date.now() is the number of ms of the current date.

 

 const formik = useFormik({
        initialValues: {
            departureTime: Date.now(),
        },
        validate,
        onSubmit: values => {
            alert(JSON.stringify(values, null, 2));
        },
    });

<LocalizationProvider dateAdapter={AdapterDateFns}>
	<DatePicker
		label="Departure Date"
        id="departureDate"
        name="departureDate"
        value={formik.values.departureDate}
        onChange={(value) => {
        		formik.setFieldValue('departureDate', Date.parse(value));
        		}}
		renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>

Mohamed Atef Date : 2022-02-14

Glad you find the solution :)

nico Date : 2022-02-14

Thanks Mohamed again.

I started using React only 2 weeks ago with asp.net core as web api.

Can you advice me books, websites to master asap react, redux for the front with asp.net core for the backend?

I guess you work more with nodejs, react than with asp.net core though :)

So any good resource for react, redux etc will be welcome. شكرا

Mohamed Atef Date : 2022-02-14

You can check this Youtube channel  https://youtu.be/Ke90Tje7VS0
And then you can move to other websites & sources especially the documentation but for the ASP.net I have no idea about it 

Mati Date : 2022-06-24

Thank you verymuch both of you guys !! This post was the only one that helped me to resolve my problem with the data Picker and formik!! 

Leave a comment

Join us

Join our community and get the chance to solve your code issues & share your opinion with us

Sign up Now

Related posts

[solved] Expected a conditional expression and instead saw an assignment
Publish date: 2021-11-29 | Comments: 0

Tag: React js

How to get the selected object in "Autocomplete material ui"?
Publish date: 2021-12-22 | Comments: 2

Tag: React js

React Redux : Connect is not called
Publish date: 2022-03-02 | Comments: 1

Tag: React js

[solved] Reactjs is not updating the props
Publish date: 2022-02-04 | Comments: 2

Tag: React js

Warning: React.jsx: type is invalid
Publish date: 2022-05-06 | Comments: 1

Tag: React js