React Formik 외부에서 submit Form 사용
현재의 동작
<Formik
isInitialValid
initialValues={{ first_name: 'Test', email: 'test@mail.com' }}
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>
);
}}
/>
https://github.com/jaredpalmer/formik/issues/73#issuecomment-317169770에서 이 솔루션을 시도하고 있지만 항상 반환됩니다.Uncaught TypeError: _this.props.onSubmit is not a function
가 때console.log(this.form)
submitForm
★★★★★★ 。
해결방법은 없나요?
- Formik 버전 : 최신 - 리액트 버전 : v16 - OS : Mac OS
리액트 훅을 통한 솔루션이 무엇인지 궁금해 하는 분들을 위해:
Formik 2.x, 이 답변에서 설명한 바와 같이
// import this in the related component
import { useFormikContext } from 'formik';
// Then inside the component body
const { submitForm } = useFormikContext();
const handleSubmit = () => {
submitForm();
}
이 솔루션은 컨텍스트 API를 사용하기 때문에 Formik 구성 요소 내의 구성 요소에만 작동합니다.어떤 이유로 외부 컴포넌트 또는 Formik이 실제로 사용되는 컴포넌트에서 수동으로 제출하고 싶은 경우에도 실제로 사용할 수 있습니다.innerRef
가 TLDR의 합니다.<Formik>
★★★★★★★★★★★★★★★★★」withFormik()
컴포넌트 의 경우는, 「」, 「」를 합니다.innerRef
이하에 답해 주세요.
폼익 1.5.x+
// Attach this to your <Formik>
const formRef = useRef()
const handleSubmit = () => {
if (formRef.current) {
formRef.current.handleSubmit()
}
}
// Render
<Formik innerRef={formRef} />
수 요.formikProps.submitForm
전송로 전송한 후 컴포넌트로부터의 (Formik의 프로그램 전송).
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;
제가 찾은 최고의 솔루션은 https://stackoverflow.com/a/53573760에 기재되어 있습니다.
답변을 여기에 복사:
양식에 "id" 특성 추가: id='my-form'
class CustomForm extends Component {
render() {
return (
<form id='my-form' onSubmit={alert('Form submitted!')}>
// Form Inputs go here
</form>
);
}
}
그런 다음 양식 외부에 있는 대상 단추의 "양식" 속성에 동일한 ID를 추가합니다.
<button form='my-form' type="submit">Outside Button</button>
이제 'Outside Button' 버튼은 양식 안에 있는 것처럼 완전히 동일합니다.
주의: IE11에서는 지원되지 않습니다.
같은 문제를 안고 매우 간단한 해결책을 찾았습니다.이것이 도움이 되었으면 합니다.
는 쉽게 할 수 html
★★★★★★★★★★★★를 붙이면,id
를 달다form
의 '버튼해서 '을할 수 .form
붙이다
예:
<button type="submit" form="form1">
Save
</button>
<form onSubmit={handleSubmit} id="form1">
....
</form>
양식과 버튼을 다른 위치에 배치할 수 있습니다.
이 버튼을 누르면 폼 제출 기능이 트리거되고 정상적으로 프로세스를 계속하는 폼이 캡처됩니다.(버튼이 렌더링되는 동안 폼이 화면에 렌더링되는 한 폼과 버튼이 어디에 있든 작동됩니다.)
컴포넌트로 컴포넌트로 변환됩니다.useFormikContext
트리 아래 임의의 장소에서 submit을 사용할 수 있는 방법을 제공합니다.
const { values, submitForm } = useFormikContext();
PS: 이것은 실제로 전화할 필요가 없는 사용자에게만 해당됩니다.Formik
컴포넌트입니다.그래서 참조를 사용하는 대신에Formik
트리의 합니다.useFormikContext
, 꼭 해야 하는 하지 않으면 안 됩니다.Formik
그럼 이렇게 돼요.useRef
.
<Formik innerRef={formikRef} />
https://formik.org/docs/api/useFormikContext
2021년에는 16.13.1을 사용하여 다음과 같은 몇 가지 요건을 충족했습니다.
- Submit ] / [ Reset ]은 [Submit] / [ ]버튼 할 수 .
<Formik>
수 하는 게 것 같아요useFormikContext
내 것보다 간단하기 때문에 대답할 수 있습니다.(내 것으로, 송신하는 폼을 변경할 수 있습니다(앱바는 1개이지만, 유저는 복수의 폼을 참조할 수 있습니다). - 외부 제출/재설정 버튼은 Formik 양식을 전송하고 재설정할 수 있어야 합니다.
- 이 더러워질 컴포넌트는 의 "/"를할 수 합니다).
dirty
□□□□□□□□★
은 다음과 의 서로 중첩된 두 개의 및 폼)를 링크하는 데 몇 공급자를 .저는 새로운 콘텍스트 프로바이더를 만들었습니다.이 프로바이더는 앱의 서로 다른 네스트된 브랜치(글로벌 앱바 및 다른 폼)에 있는 외부 컴포넌트를 링크하기 위한 것입니다.을 사용법온 다른 단의 형태뿐만 , 1개의 형태에 적응하는 것도 필요합니다.<Formik>
이렇게 말합니다.
다음 예제에서는 TypeScript를 사용하지만 javascript만 알고 있다면 콜론 뒤에 있는 항목을 무시하면 JS에서도 마찬가지입니다.
<FormContextProvider>
Formik 항목에 액세스해야 하는 서로 다른 컴포넌트를 모두 랩할 수 있을 정도로 앱의 용량이 높습니다.[ ] :
<FormContextProvider>
<MyAppBar />
<MyPageWithAForm />
</FormContextProvider>
Form Context Provider는 다음과 같습니다.
import React, { MutableRefObject, useRef, useState } from 'react'
import { FormikProps, FormikValues } from 'formik'
export interface ContextProps {
formikFormRef: MutableRefObject<FormikProps<FormikValues>>
forceUpdate: () => void
}
/**
* Used to connect up buttons in the AppBar to a Formik form elsewhere in the app
*/
export const FormContext = React.createContext<Partial<ContextProps>>({})
// https://github.com/deeppatel234/react-context-devtool
FormContext.displayName = 'FormContext'
interface ProviderProps {}
export const FormContextProvider: React.FC<ProviderProps> = ({ children }) => {
// Note, can't add specific TS form values to useRef here because the form will change from page to page.
const formikFormRef = useRef<FormikProps<FormikValues>>(null)
const [refresher, setRefresher] = useState<number>(0)
const store: ContextProps = {
formikFormRef,
// workaround to allow components to observe the ref changes like formikFormRef.current.dirty
forceUpdate: () => setRefresher(refresher + 1),
}
return <FormContext.Provider value={store}>{children}</FormContext.Provider>
}
「」를 하는 .<Formik>
다음 행을 추가합니다.
const { formikFormRef } = useContext(FormContext)
컴포넌트에서는 이 를 「」에 합니다.<Formik>
★★★★
innerRef={formikFormRef}
컴포넌트 에서 첫 은 " " " 입니다.<Formik>
이것입니다(한 것은, 「이것」의 ).<FormContextRefreshConduit />
sline)를 참조해 주세요.
<Formik
innerRef={formikFormRef}
initialValues={initialValues}
...
>
{({ submitForm, isSubmitting, initialValues, values, setErrors, errors, resetForm, dirty }) => (
<Form>
<FormContextRefreshConduit />
...
송신/리셋 버튼이 있는 컴포넌트에는 다음과 같은 것이 있습니다.「 」의 .formikFormRef
export const MyAppBar: React.FC<Props> = ({}) => {
const { formikFormRef } = useContext(FormContext)
const dirty = formikFormRef.current?.dirty
return (
<>
<AppButton
onClick={formikFormRef.current?.resetForm}
disabled={!dirty}
>
Revert
</AppButton>
<AppButton
onClick={formikFormRef.current?.submitForm}
disabled={!dirty}
>
Save
</AppButton>
</>
)
}
ref
하지만 Formik 메서드의 Formik 메서드에 할 수 .dirty
재산(재산) FormContextRefreshConduit
forceUpdate
이치노
감사합니다. 저는 다른 답변에서 영감을 얻어 제 모든 요구사항을 충족하는 방법을 찾았습니다.
Formik과 함께 사용한다면 다음과 같은 이점이 있습니다.
const handleSubmitThroughRef = () => {
newFormRef.current.dispatchEvent(
new Event("submit", { cancelable: true, bubbles: true })
);
};
폼에 규칙적인 ref를 붙이면 됩니다.
<form
ref={newFormRef}
onSubmit={handleSubmit}
>
범인을 찾아내다
이상 없다onSubmitCallback
포믹 소품 위에. 돼요.onSubmit
드셔보세요
const submitForm =({ values, setSubmiting }) =>{/...여기서 작업하세요}
<Formik on Submit={(값, {set Submiting }}=> submit Form({값, set Submiting})> {()=>(/...여기서 뭔가 실행)}
또 다른 간단한 방법은 useState를 사용하여 소품을 하위 폼 컴포넌트에 전달하는 것입니다.여기서 useEffect 후크를 사용하여 state를 설정할 수 있습니다.
const ParentComponent = () => {
const [submitFunc, setSubmitFunc] = useState()
return <ChildComponent setSubmitFunc={setSubmitFunc}>
}
const ChildComponent= ({ handleSubmit, setSubmitFunc }) => {
useEffect(() => {
if (handleSubmit) setSubmitFunc(() => handleSubmit)
}, [handleSubmit, setSubmitFunc])
return <></>
}
React Class 컴포넌트에 단계별로 구현했습니다.
1 - 폼 오브젝트의 참조를 유지하기 위해 "ref" 변수를 선언했습니다(useRef는 함수 컴포넌트에서만 유효하므로 React.createRef() 함수를 사용하여 다음과 같이 코드화했습니다).
constructor(props) {
super(props);
this.visitFormRef = React.createRef();
}
2 - formik 폼에 "innerRef" 기능이 있기 때문에 위의 ref 변수를 할당했습니다.
<Formik
initialValues={initialValues}
onSubmit={(values) => onSubmit(values)}
validationSchema={validationSchema}
enableReinitialize={true}
innerRef={this.visitFormRef} //<<--here
>
3- 아래 함수를 선언한 폼이 아닌 다른 곳에서 폼의 제출 이벤트를 트리거하려면:
triggerFormSubmit = () => {
if (this.visitFormRef.current)
this.visitFormRef.current.handleSubmit();
}
4 - 마지막으로 외부 버튼에서 위의 함수를 호출했습니다.
<Button onClick={() => this.triggerFormSubmit()} />
혼동하지 않도록 주의해 주세요.formik 형식에 대응된 onSubmit(values) 함수는 아직 존재하며 값에서 를 가져옵니다.방금 외부 버튼에서 작동시킨 겁니다
다음은 ref를 사용하여 사용자가 외부 제출 버튼을 클릭했을 때 내부 숨겨진 제출 버튼을 클릭하는 시뮬레이션을 통해 얻은 방법입니다.
const hiddenInnerSubmitFormRef = useRef(null);
const handleExternalButtonClick = () => {
hiddenInnerSubmitFormRef.current.click();
}
return (
<>
{/* External Button */}
<button onClick={handleExternalButtonClick}>
External Submit
</button>
<Formik onSubmit={values => console.log(values)}>
{() => (
<Form>
{/* Hide Button /*}
<button type="submit" ref={hiddenInnerSubmitFormRef} className="hidden">
Submit
</button>
</Form>
)}
</Formik>
</>
)
언급URL : https://stackoverflow.com/questions/49525057/react-formik-use-submitform-outside-formik
'programing' 카테고리의 다른 글
MongoDB 전체 및 부분 텍스트 검색 (0) | 2023.03.27 |
---|---|
Wordpress REST API에서 카테고리/태그 목록을 검색하는 방법 (0) | 2023.03.27 |
노드/도커를 빌드할 때 uid/gid를 가져올 수 없습니다. (0) | 2023.03.27 |
Oracle에서 모든 테이블 제약 조건 사용 안 함 (0) | 2023.03.27 |
wp_mail을 사용하여 첨부 메일을 보내는 방법 (0) | 2023.03.27 |