如何从另一个子组件调用子提交方法



我试图解决这个2天,但不能。当使用Typescript和react-hook-form的ModalContent组件调用onApply函数时,如何在CreateProject组件中调用onSubmit方法。想法:当我在ModalContent点击按钮时,它应该调用CreateProject中的react-hook-form onSumbit方法。然后CreateProject在这两个子组件的父组件中调用onSubmit。

或者这种组件结构的想法是错误的?

谢谢大家的回答。

父组件:

import { ModalBody } from '../../components/modals'
import useCreateProject from '../../api/hooks/createProject'
export default function New(): JSX.Element {
const [modalVisible, setModalVisible] = React.useState(true)
const onSubmit = useCreateProject((data) => {
const { createProject } = data.data.data
console.log(data)
})
const onApply = () => {
console.log(123)
}
return (
<ModalContent
name={'Create project'}
visible={modalVisible}
onApply={onApply}
onCancel={() => setModalVisible(false)}
>
<ModalBody>
<CreateProject onSubmit={onSubmit.mutate} />
</ModalBody>
</ModalContent>
)
}

子组件

import React from 'react'
import Input from '../Inputs/Input'
import Textarea from '../Inputs/Textarea'
import FileUploader from '../uploader/FileUploader'
import Tasks from '../forms/Tasks'
import { useForm } from 'react-hook-form'
import {
draftBudgetMaxLength,
projectNameMaxLength,
descriptionMaxLength,
} from '../../constants/createProjectModal'
import ButtonSecondary from '../buttons/ButtonSecondary'
export interface IModalInputs {
create_project_name: string
}
export interface ICreateProjectProps {
onSubmit: (values: IModalInputs) => void
}
const СreateProject: React.FC<ICreateProjectProps> = ({
onSubmit,
}): React.ReactElement => {
const {
register,
getValues,
control,
handleSubmit,
formState: { errors },
} = useForm<IModalInputs>()
return (
<>
<form onSubmit={handleSubmit(() => onSubmit(getValues()))}>
<div className="p-4">
<div className="flex flex-col -m-1.5">
<div className="m-1.5">
<Input
type="text"
label="Project name"
name="create_project_name"
register={register}
error={errors.create_project_name}
options={{
required: true,
maxLength: projectNameMaxLength,
}}
/>
</div>
</div>
</div>
</form>
</>
)
}
export default СreateProject

带有click事件的子组件

import React from 'react'
import Image from 'next/image'
import close from '../../assets/close.svg'
import ButtonSecondary from '../buttons/ButtonSecondary'
interface IModalContentProps {
children: React.ReactElement
onApply?: () => void
visible: boolean
buttonName?: string
}
const ModalContent: React.FC<IModalContentProps> = ({
name,
children,
visible,
onCancel,
onApply,
buttonName,
}) => {
return (
<>
{visible && (
<div className="flex p-4 space-x-2 justify-end">
{children}
<ButtonSecondary
click={onApply}
type={'submit'}
label={buttonName || 'Ok'}
id={buttonName}
shown={true}
styleClass="styleClass"
paddingClass="py-2 py-2 pr-4 pl-2"
/>
</div>      
)}
</>
)
}
export default ModalContent

useRef和useImperativeHandle钩子解决了这个问题。

父:

export default function New(): JSX.Element {
const [modalVisible, setModalVisible] = React.useState(true)
const childRef = React.useRef<any>()
const onSubmit = useCreateProject((data) => {
const { createProject } = data.data.data
console.log(data)
})
return (
<ModalContent
name={'Create project'}
visible={modalVisible}
onApply={() => childRef.current.SubmitForm()}
onCancel={() => setModalVisible(false)}
>
<ModalBody>
<CreateProject onSubmit={onSubmit.mutate} ref={childRef} />
</ModalBody>
</ModalContent>
)
}

孩子:

export interface IModalInputs {
create_project_name: string
}
export interface ICreateProjectProps {
onSubmit: (values: IModalInputs) => void
}
function CreateProject(props: ICreateProjectProps, ref) {
const {
register,
getValues,
control,
handleSubmit,
formState: { errors },
} = useForm<IModalInputs>()
useImperativeHandle(ref, () => ({
SubmitForm() {
handleSubmit(() => props.onSubmit(getValues()))()
},
}))
return (
<>
<form ref={ref}>
<div className="p-4">
<div className="flex flex-col -m-1.5">
<div className="m-1.5">
<Input
type="text"
label="Project name"
name="create_project_name"
register={register}
error={errors.create_project_name}
options={{
required: true,
maxLength: projectNameMaxLength,
}}
/>
</div>

</div>
</div>
</form>
</>
)
}
export default React.forwardRef(CreateProject)

最新更新