Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Formik use submitForm outside <Formik />

Tags:

reactjs

formik

Current Behavior

<Formik     isInitialValid     initialValues={{ first_name: 'Test', email: '[email protected]' }}     validate={validate}     ref={node => (this.form = node)}     onSubmitCallback={this.onSubmitCallback}     render={formProps => {         const fieldProps = { formProps, margin: 'normal', fullWidth: true, };         const {values} = formProps;         return (             <Fragment>                 <form noValidate>                     <TextField                         {...fieldProps}                         required                         autoFocus                         value={values.first_name}                         type="text"                         name="first_name"                      />                      <TextField                         {...fieldProps}                         name="last_name"                         type="text"                     />                      <TextField                         {...fieldProps}                         required                         name="email"                         type="email"                         value={values.email}                      />                 </form>                 <Button onClick={this.onClick}>Login</Button>             </Fragment>         );     }} /> 

I'm trying this solution https://github.com/jaredpalmer/formik/issues/73#issuecomment-317169770 but it always return me Uncaught TypeError: _this.props.onSubmit is not a function

When I tried to console.log(this.form) there is submitForm function.

Any solution guys?


- Formik Version: latest - React Version: v16 - OS: Mac OS

like image 323
ssuhat Avatar asked Mar 28 '18 02:03

ssuhat


Video Answer


2 Answers

Just for anyone wondering what's the solution via React hooks :

Formik 2.x, as explained in this answer

// import this in the related component import { useFormikContext } from 'formik';  // Then inside the component body const { submitForm } = useFormikContext();  const handleSubmit = () => {   submitForm(); } 

Keep in mind that solution only works for components inside a Formik component as this uses the context API. If for some reason you'd like to manually submit from an external component, or from the component the Formik is actually used from, you can actually still use the innerRef prop.

TLDR ; This context answers works like a charm if the component that you're submitting from is a child of a <Formik> or withFormik() component, otherwise, use the innerRef answer below.

Formik 1.5.x+

// Attach this to your <Formik> const formRef = useRef()  const handleSubmit = () => {   if (formRef.current) {     formRef.current.handleSubmit()   } }  // Render <Formik innerRef={formRef} /> 
like image 126
Eric Martin Avatar answered Sep 17 '22 13:09

Eric Martin


You can bind formikProps.submitForm (Formik's programatic submit) to a parent component and then trigger submission from the parent:

import React from 'react'; import { Formik } from 'formik';  class MyForm extends React.Component {     render() {         const { bindSubmitForm } = this.props;         return (             <Formik                 initialValues={{ a: '' }}                 onSubmit={(values, { setSubmitting }) => {                     console.log({ values });                     setSubmitting(false);                 }}             >                 {(formikProps) => {                     const { values, handleChange, handleBlur, handleSubmit } = formikProps;                      // bind the submission handler remotely                     bindSubmitForm(formikProps.submitForm);                      return (                         <form noValidate onSubmit={handleSubmit}>                             <input type="text" name="a" value={values.a} onChange={handleChange} onBlur={handleBlur} />                         </form>                     )                 }}             </Formik>         )     } }  class MyApp extends React.Component {      // will hold access to formikProps.submitForm, to trigger form submission outside of the form     submitMyForm = null;      handleSubmitMyForm = (e) => {         if (this.submitMyForm) {             this.submitMyForm(e);         }     };     bindSubmitForm = (submitForm) => {         this.submitMyForm = submitForm;     };     render() {         return (             <div>                 <button onClick={this.handleSubmitMyForm}>Submit from outside</button>                 <MyForm bindSubmitForm={this.bindSubmitForm} />             </div>         )     } }  export default MyApp; 
like image 37
Elise Chant Avatar answered Sep 20 '22 13:09

Elise Chant