Доступ к параметру функции из другой функции в javascript / typescript - PullRequest
0 голосов
/ 10 мая 2019

Как я могу получить доступ к параметру лямбда-функции из другой функции?

Я пытаюсь получить доступ к значению formikBag, созданному внутри render={...}, из функции handleClick.

Сначала я попытался с помощью useState hook установить состояние, а затем получить к нему доступ, но я получаю 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 Ответ

3 голосов
/ 10 мая 2019

Вам нужно изменить иерархию компонентов, чтобы сделать это правильно. Обернув свой модал в компонент 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>
    );
  }
}

Здесь работает над CodeSandbox .

Я никогда раньше не использовал Ant, но дизайн их модального компонента делает это более сложным, чем должно быть.

...