简体   繁体   中英

Access the parameter of a function from another function in javascript / typescript

How can I access the parameter of a lambda function from another function?

I'm trying to access the value of formikBag , created inside render={...} , from the handleClick function.

I first tried with useState hook to set the state and later access it, but I get undefined .

export const Form: React.FC<FormProps> = (props) => {   
    const MyFormikForm = () => {
        return (
            <Formik
                initialValues={...}
                onSubmit={...)
                validationSchema={.}
                render={(formikBag: FormikProps<FormValues>) => <form>My Form</form>}
            />
        )
    }

    const handleClick = () => {
        showModal(({ show }) => {
            // How could I get access the formikBag variable here?                          

            // do stuff
            return (
                <ModalAntd>
                    <MyFormikForm />
                </ModalAntd>
            )
        })
    }

    return <ButtonComponent onClick={handleClick} />
}

You need to rearrange your component hierarchy to do this properly. By wrapping your modal in the Formik component (rather than the other way around) you can access the Formik bag or anything else you need.

I'm not completely sure I fully understand what you're doing but I think this is close:

/**
 * Form that can appear in a modal or directly.
 */
function ExampleForm({
  isSubmitting,
  showButton
}: {
  isSubmitting: boolean;
  showButton: boolean;
}) {
  return (
    <Form>
      <label htmlFor="field">Some Field</label>
      <Field name="field" type="text" />
      {showButton && (
        <Button loading={isSubmitting} htmlType="submit">
          Submit
        </Button>
      )}
    </Form>
  );
}

/**
 * Show a form in a modal or directly.
 */
class ExampleFormWrapper extends React.PureComponent<
  { showModal: boolean },
  { isOpen: boolean }
> {
  state = { isOpen: false };

  /**
   * Close the modal form.
   */
  hideForm = () => this.setState({ isOpen: false });

  /**
   * Open the form in a modal.
   */
  openForm = () => this.setState({ isOpen: true });

  /**
   * Submit the form with fake wait to simulate a real submission.
   */
  onSubmit = (
    values: FormValues,
    { setSubmitting }: FormikActions<FormValues>
  ) => {
    console.log(values);
    window.setTimeout(() => {
      if (this.props.showModal) {
        this.hideForm();
      } else {
        setSubmitting(false);
      }
    }, 2000);
  };

  /**
   * Render either a form or a button that will show the form in a modal.
   */
  render() {
    return (
      <React.Fragment>
        {this.props.showModal && <Button onClick={this.openForm}>Open</Button>}
        <Formik initialValues={{ field: "" }} onSubmit={this.onSubmit}>
          {({ handleSubmit, isSubmitting }) =>
            this.props.showModal ? (
              <Modal
                onCancel={this.hideForm}
                onOk={handleSubmit}
                okButtonProps={{ loading: isSubmitting }}
                okText="Submit"
                title="Form"
                visible={this.state.isOpen}
              >
                <ExampleForm isSubmitting={isSubmitting} showButton={false} />
              </Modal>
            ) : (
              <ExampleForm isSubmitting={isSubmitting} showButton={true} />
            )
          }
        </Formik>
      </React.Fragment>
    );
  }
}

Here it is working on CodeSandbox .

I've never used Ant before but the design of their modal component makes this more difficult that it should be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM