6

I am using react hooks and useRef to call a child method from the parent (see here: Call child method from parent)

Specifically, I am trying to call the formik submitForm method which is located in my child component from my parent component. I know there are other ways to do this (React Formik use submitForm outside <Formik />) but i would really like to use useRef.

const Auth1 = forwardRef((props, ref) => {

  useImperativeHandle(ref, () => ({
    handleSubmit() {
      ///////////formik submitForm function goes here
    }
  }));

  return(
    <div>
      <Formik
          initialValues={props.initValues}
          validationSchema={Yup.object().shape({
            name: Yup.string().required('Required'),
          })}
          onSubmit={(values, actions) => {
            console.log(values)
          }}
          render={({ values }) => (
            <Form>
                <Field
                  name="name"
                  value={values.name}
                  component={TextField}
                  variant="outlined"
                  fullWidth
                />
            </Form>
          )}
        />
    </div>
  )

})

There must be a way to bind the submitForm function out of the component and into the body of my Auth1 component, but imnot quite too sure how.

Any help is greatlly appreciated, thanks!

wei
  • 557
  • 1
  • 10
  • 24

1 Answers1

8

You can pull the handleSubmit function out of the useImperativeHandle call the exposed method from parent using ref

const Auth1 = forwardRef((props, ref) => {

  const handleSubmit = (values, actions) => {
    ///////////formik submitForm function goes here
  }
  useImperativeHandle(ref, () => ({
    handleSubmit
  }), []);

  return(
    <div>
      <Formik
          initialValues={props.initValues}
          validationSchema={Yup.object().shape({
            name: Yup.string().required('Required'),
          })}
          onSubmit={handleSubmit}
          render={({ values }) => (
            <Form>
                <Field
                  name="name"
                  value={values.name}
                  component={TextField}
                  variant="outlined"
                  fullWidth
                />
            </Form>
          )}
        />
    </div>
  )
})

Now from the parent you could have

const Parent = () => {
    const authRef = useRef(null);
    ...

    const callSubmit = () => {
        authRef.current.handleSubmit(values, actions);
    }
    return (
          <>
             {/* */}
             <Auth1 ref={authRef} />
          </>
    )

}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400