从javascript / typescript中的另一个函数访问函数的参数

时间:2019-05-10 10:25:47

标签: javascript reactjs typescript formik

如何从另一个函数访问lambda函数的参数?

我正在尝试通过formikBag函数访问在render={...}内部创建的handleClick的值。

我首先尝试使用useState钩子来设置状态,然后再访问它,但得到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} />
}

1 个答案:

答案 0 :(得分:3)

您需要重新排列组件层次结构才能正确执行此操作。通过将模态包装在Formik组件中(而不是相反),您可以访问Formik包或其他所需的东西。

我不确定我是否完全了解您在做什么,但我认为这已经很接近了:

/**
 * 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

我以前从未使用过Ant,但是其模态组件的设计使它本应变得更加困难。