React:从父组件触发子组件表单onSubmit无效,排查代码问题
问题解决思路
你的代码里有两个关键问题:
- 拼写错误:表单的事件属性写成了
onSumit,正确的应该是onSubmit,这个笔误会直接导致表单的提交逻辑完全不触发。 - Ref绑定对象不对:你把父组件传的ref绑在了自定义
Button组件上,多数UI库的自定义按钮(比如Antd的Button)不会默认把ref透传到原生button DOM节点,所以父组件的submitRef.current根本拿不到能触发点击的原生元素。而且就算能触发按钮点击,这种方式也不如直接调用表单的原生提交行为靠谱。
正确的实现方式有两种:
方式一:把Ref绑定到表单元素上
子组件里把父组件的ref直接绑到<form>标签,父组件调用表单的submit()方法就能触发onSubmit逻辑:
// 父组件代码 import { useRef } from 'react'; import ChildComponent from './ChildComponent'; function ParentComponent() { const submitRef = useRef(null); const triggerSubmit = () => { submitRef.current?.submit(); }; return ( <div> <button onClick={triggerSubmit}>父组件按钮触发提交</button> <ChildComponent ref={submitRef} /> </div> ); } // 子组件代码 import { forwardRef } from 'react'; import { Button } from 'antd'; // 假设用的是Antd组件 const ChildComponent = forwardRef((props, ref) => { const handleSubmit = (e) => { e.preventDefault(); // 这里写你的表单提交逻辑 console.log('表单提交成功'); }; return ( <form ref={ref} onSubmit={handleSubmit}> {/* 表单输入项 */} <input type="text" placeholder="输入内容" /> <Button type="submit">子组件提交按钮</Button> </form> ); }); export default ChildComponent;
方式二:通过props传递提交方法(更符合React数据流)
不用ref,子组件把提交方法传给父组件,父组件直接调用这个方法:
// 父组件代码 import { useRef } from 'react'; import ChildComponent from './ChildComponent'; function ParentComponent() { const submitFn = useRef(null); const triggerSubmit = () => { submitFn.current?.(); }; return ( <div> <button onClick={triggerSubmit}>父组件按钮触发提交</button> <ChildComponent getSubmitFn={(fn) => submitFn.current = fn} /> </div> ); } // 子组件代码 import { useRef, useEffect } from 'react'; import { Button } from 'antd'; const ChildComponent = ({ getSubmitFn }) => { const formRef = useRef(null); const handleSubmit = (e) => { e.preventDefault(); // 表单提交逻辑 console.log('表单提交成功'); }; useEffect(() => { // 把提交方法传给父组件 getSubmitFn(() => formRef.current?.submit()); }, [getSubmitFn]); return ( <form ref={formRef} onSubmit={handleSubmit}> <input type="text" placeholder="输入内容" /> <Button type="submit">子组件提交按钮</Button> </form> ); }; export default ChildComponent;
内容的提问来源于stack exchange,提问作者vaibhav deep
相关产品推荐
相关产品推荐

