缘由
遇到这样的一个问题,原先是用户点击校验的按钮完成无误之后,后面点击确定提交表单。
但是测试过程中需要在提交表单的时候先给两个校验完成之后才可以提交。其中校验失败返回提示消息,且不可提交。这样一来事情就变得复杂了呀。
分析
代码分析:由于图中两个校验是写在不同的子组件,确定提交表单是一个父组件。
所以想到了父组件调用子组件的方法,去官方文档看了一下useimperativehandle使用方法。
文档
如何使用
import { useState, useImperativeHandle ,useRef} from 'react';
// props子组件中需要接受ref
function ChildComp({ cRef }) {
const [val, setVal] = useState();
function rules(a) {
setVal(a)
console.log(a);
}
// 此处注意useImperativeHandle方法的的第一个参数是目标元素的ref引用
useImperativeHandle(cRef, () => ({
// changeVal 就是暴露给父组件的方法
changeVal: (newVal) => {
rules(newVal);
}
}));
return (
<div>{val}</div>
)
}
export default function App() {
const childRef = useRef();
const updateChildState = () => {
// changeVal就是子组件暴露给父组件的方法
childRef.current.changeVal(99);
}
return (
<>
{/* 此处注意需要将childRef通过props属性从父组件中传给自己 cRef={childRef} */}
<ChildComp cRef={childRef} />
<button onClick={updateChildState}>触发子组件方法</button>
</>
)
}
结合需求
现在需要验证表单错误的时候不可提交,这时候想到了用promise,给表单的验证方法用promise包裹起来,请求成功返回成功的promise,失败返回失败
function rules(a) {
return new Promise((res, rej) => {
request({
url: '/demo/api',
needMask: true,
data,
success: () => {
res()
message.success('校验成功,没有错误')
},
fail: () => {
rej()
message.error('验证失败')
}
})
})
}
由于是两个验证,所以得两个验证都成功才可提交,可以用promise.all([])
,这样就问题就解决了
function submit(){
let PromiseRules = [];
PromiseRules.push(childRef.current.childFun(data));
PromiseRules.push(childRef1.current.childFun(data));
Promise.all(PromiseRules)
.then((res) => {
request({
url: "/demo1/api",
needMask: true,
data: { data },
success: (res) => {
message.success("保存成功");
},
fail: (err) => {
message.error(err);
},
});
})
.catch((err) => {
console.log(err);
});
}