Search code examples
reactjsformikreact-datepicker

How to use withFormik Field with react-datepicker?


I am trying to send my dob data from my Main class to a child component (RegisterAccount.jsx) and validate it at child component using yup and withFormik Field. The problem is that:

  1. I could not make yup or formik/yup to validate dob field.
  2. DatePicker doesn't show selected value inside the textbox after selected.

Please check my below code:

Here is my Main.jsx class

// Some imports were removed to keep everything looks cleaner
import RegisterAccount from "RegisterAccount.jsx";

class Main extends React.Component {
     constructor(props) {
          super(props);

          this.state = {
             dob: ""
          }
     }

    render() {
        return (
            <Container fluid>
              <Switch>
                <Route exact path="/" render={() => <RegisterAccount data={this.state.dob} />} />
              </Switch>
            </Container>
        )
    }
}

export default Main;

Here is my RegisterAccount.jsx

// Some imports were removed to keep everything looks cleaner
import { Form as FormikForm, Field, withFormik } from "formik";
import * as Yup from "yup";
import DatePicker from "react-datepicker";


const App = ({ props }) => (
  <FormikForm className="register-form  " action="">
    <h3 className="register-title">Register</h3>
    <Form.Group className="register-form-group">
      <DatePicker
         tag={Field}
         selected={props.data.dob}
         onChange={(e, val) => {
             console.log(this);
             this.value=e;
             props.data.dob = e;
             console.log(props.data.dob);
         }}
         value="01-01-2019"
         className="w-100"
         placeholderText="BIRTH DATE"
         name="dob" />
      {touched.username && errors.username && <p>{errors.username}</p>}
    </Form.Group>
  </FormikForm>
);

const FormikApp = withFormik({
  mapPropsToValues({ data }) {
    return {
      dob: data.dob || ""
    };
  },
validationSchema: Yup.object().shape({
    dob: Yup.date()
            .max(new Date())

})(App);


export default FormikApp;


Solution

  • Use setFieldValue method from formik's injected props.

    Define it on onChange handler for your inputsetFieldValue('dob','Your Value').

    You can access it from

    const MyForm = props => {
      const {
        values,
        touched,
        errors,
        handleChange,
        handleBlur,
        handleSubmit,
        setFieldValue
      } = props;
      return (
        <form onSubmit={handleSubmit}>
          <input
            type="text"
            onChange={e => {
              setFieldValue("name", "Your value"); // Access it from props
            }}
            onBlur={handleBlur}
            value={values.name}
            name="name"
          />
        </form>
      );
    };
    const MyEnhancedForm = withFormik({
      // your code
    })(MyForm)
    

    Reference - https://jaredpalmer.com/formik/docs/api/formik#setfieldvalue-field-string-value-any-shouldvalidate-boolean-void