Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reactjs - Formik form does not fire submit on return key press

I have the following form written in React using Formik:

import React, { FunctionComponent } from 'react';
import { NavLink } from 'react-router-dom';
import { object, string } from 'yup';
import { Formik, FormikActions, Field, FormikProps } from 'formik';
import SimpleInput from './Fields/SimpleInput';
import FieldError from './Fields/FieldError';

interface FormValues {
  email: string;
  password: string;
}
interface OwnProps {
  onSubmit: (data: FormValues) => any;
}

const validationSchema = object().shape({
  email: string()
    .email('Please enter a valid email address')
    .required('Email is a required field'),
  password: string()
    .min(8)
    .required('Password is a required field'),
});

type Props = OwnProps;

const LoginForm: FunctionComponent<Props> = ({ onSubmit }) => {
  const initialValues = {
    email: '',
    password: '',
  };

  const onFormSubmit = async (values: FormValues, { setSubmitting }: FormikActions<FormValues>) => {
    await onSubmit(values);
    setSubmitting(false);
  };

  return (
    <Formik
      onSubmit={onFormSubmit}
      initialValues={initialValues}
      validationSchema={validationSchema}
      render={({ handleSubmit, isSubmitting }: FormikProps<FormValues>) => (
        <form className="ipx-form sign" onSubmit={handleSubmit}>
          <h1>Sign in</h1>
          <div className="ipx-register-here">
            ( Don&#39;t have an account? ) &nbsp;
            <NavLink to="/register">Register here</NavLink>
          </div>
          <br />
          <Field name="email" type="email" component={SimpleInput} label="Email Address" placeholder="Email" />
          <FieldError name="email" />
          <br />
          <br />
          <div className="fields">
            <Field name="password" type="password" component={SimpleInput} label="Password" placeholder="Password" />
            <FieldError name="password" />
          </div>
          <br />
          Forgot <NavLink to="/forgot-password">password?</NavLink>
          <br />
          <button className="button ipx-submit-button" id="ipx-login-submit" type="submit" disabled={isSubmitting}>
            <span className="ladda-label">Sign in</span>
          </button>
        </form>
      )}
    />
  );
};

export default LoginForm;

Which works fine if I click the button to submit the form (it dispatches the Redux action and logs the user in), however when I try to submit the form with a Return/Enter key press it fails to catch the event. I tried logging the event in the onSubmit prop of the <form> element but no event is triggered on Enter press at all. This same form was previously written using redux-form and the Return key functionality worked as it should.

I initially thought it might be due to the asynchronous form handling but I switched to a regular synchronous function and it did not work as well.

Has anyone ever experienced something similar, and if so, please share any fixes.

Thank you!

Codesandbox

like image 745
Andrej Naumovski Avatar asked Jan 24 '19 14:01

Andrej Naumovski


People also ask

How submit form when Enter key is pressed ReactJS?

To submit a form using the Enter key in React: Add a button element with type set to submit . Add an onSubmit prop that points to a submit handler function. Every time the user presses Enter, the handle submit function will be invoked.

What is dirty Formik?

Returns true if values are not deeply equal from initial values, false otherwise. dirty is a readonly computed property and should not be mutated directly.


2 Answers

The best way that I found to solve this scenery is to call handleSubmit() method inside onKeyDown event of HTML Form Element that is child of Formik.

      <Formik
        initialValues={{
          login: '',
          senha: ''
        }}
        onSubmit={(values, { setErrors }) => {
          this.submitSignin(values, setErrors);
        }}
      >
        {props => {
          const {
            values,
            handleChange,
            handleBlur,
            handleSubmit,
          } = props;
          return (
            <form 
              onSubmit={handleSubmit} 
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  handleSubmit();
                }
              }}>
             <input 
               id="login"
               value={values.login}
               onChange={handleChange}
               onBlur={handleBlur} />
             <input 
               id="senha"
               value={values.senha}
               onChange={handleChange}
               onBlur={handleBlur} />
            </form>
          }
        </Formik>
like image 187
João Henrique Barbosa Avatar answered Sep 17 '22 21:09

João Henrique Barbosa


Maybe try using the children prop with Formik as shown here: https://jaredpalmer.com/formik/docs/api/formik#children-reactreactnode-props-formikprops-values-reactnode

And remove the form element wrapping the form. Or disable the default behavior of the form. That's what's intercepting the enter keypress behavior.

like image 38
prufrofro Avatar answered Sep 17 '22 21:09

prufrofro