背景
之前項目中使用了antd pro
中的 可編輯表格 (EditableProTable)
,在頁面中表格要經(jīng)過多層遍歷后組成的新頁面,所以我將之抽成了一個公用的組件,另外在遍歷的最外層需要通過一個按鈕統(tǒng)一提交表格數(shù)據(jù),但是提交數(shù)據(jù)之前需要對每一個表格進(jìn)行非空校驗。
思考
遍歷中引入組件這個沒啥好說的,根據(jù)以往的經(jīng)驗來說,一般要獲取某個 JSX
節(jié)點都是采用的 useRef()
這個Hook
,大多寫法如下:
const ref = useRef(null);
<div ref={ref}>...</div>
這里主要說的是怎么一次性獲取多個子組件實例,用到這個場景的也有,可能也不大多,我剛開始也在網(wǎng)上找了一大堆,基本沒有相關(guān)的答案,這整的我 cv大法
自然也用不了,可是項目又趕得急,總的想辦法解決吧,最后我盯上了ChtGPT
,通過智能答案在這里獲取到了一定的參考,如下:
既然已經(jīng)有了靈感(參考),那就依樣畫葫蘆唄,開整。
下面是我經(jīng)過項目實踐后,再次做的一個案例,希望能夠?qū)τ行枰呐笥岩恍椭?,可能寫的不夠?yōu)雅,還請大家多多包涵。如有更好的方式,請大家多多留言扶正,多謝。
實現(xiàn)
完整代碼:
import { Button, message } from "antd";
import { useImperativeHandle, useRef } from "react";
interface paramsType {
id: number,
title: string,
}
interface validateFieldsObjType {
[key: number]: boolean;
}
// 子組件
const ChildComponentPage:React.FC = (props: any) => {
const { id, title, onRef } = props;
const divStyleObj = {
width: '100%',
height: '100px',
background: 'red',
marginTop: '20px',
fontSize: '20px',
color: '#fff'
}
useImperativeHandle(onRef, () => {
return {
func
}
})
const func = ():boolean => {
console.log(`${title}(${id})被觸發(fā)了`)
if (id ===2) return false;
else return true;
}
return (
<div style={divStyleObj}>【子組件】==》{title}--{id}</div>
)
}
// 父組件
const TestRef:React.FC = () => {
const childRefs: any = useRef({});
// mock源數(shù)據(jù)
const datasource:paramsType[] = [
{ id: 1, title: '組件-天天', },
{ id: 2, title: '組件-小灰', },
{ id: 3, title: '組件-阿奇', },
{ id: 4, title: '組件-駑馬', },
{ id: 5, title: '組件-小栗', },
]
// 異步獲取所有子組件校驗狀態(tài)
const getChildRefReturnStateFn = (childRefIdsArry:any) => {
const validateFieldsObj: validateFieldsObjType = {};
childRefIdsArry.forEach((id: number, index: number) => {
const childRef = childRefs.current[id];
const childReturnState = childRef.func();
console.log('子組件實例返回狀態(tài):', id, childReturnState)
validateFieldsObj[id] = childReturnState;
})
return validateFieldsObj;
}
// 點擊事件
const clickThisFn = async () => {
const childRefIdsArry:any[] = Object.keys(childRefs.current);
const validateFieldsObj: any = await getChildRefReturnStateFn(childRefIdsArry);
console.log('子組件檢查結(jié)果:', validateFieldsObj)
const validateFieldsLen = Object.values(validateFieldsObj).filter((type)=>!type);
if (childRefIdsArry.length !== validateFieldsLen.length) console.log('校驗不通過,請再次檢查數(shù)據(jù)。')
else console.log('校驗已通過')
};
return (
<>
<div style={{ width: '100%', background: 'orange', padding: '20px' }}>
{
datasource.map(({ id, title }: paramsType, index: number) => {
return <ChildComponentPage key={id} id={id} title={title} onRef={(_ref: React.RefObject<HTMLInputElement>) => childRefs.current[id] = _ref} />
})
}
</div>
<Button type="primary" onClick={clickThisFn}>檢驗全部子組件</Button>
</>
)
};
export default TestRef;
成功運行后的界面如下:
點擊左側(cè)按鈕后,通過控制臺可以看到相關(guān)的運行信息。
知識點總結(jié)
uesRef() 作對象處理
useImperativeHandle() 父組件操作引入子組件的內(nèi)部方法
最后
關(guān)于這個問題的解決方法,就在上面的代碼里面了,如果對上面的Hook使用還不清楚的,這里就不再贅述,請自行網(wǎng)上查看。文章來源:http://www.zghlxwxcb.cn/news/detail-674401.html
如果對你有所幫助,麻煩咚咚你的黃金手指,請點贊
,搜藏
。文章來源地址http://www.zghlxwxcb.cn/news/detail-674401.html
到了這里,關(guān)于React 使用 useRef() 獲取循環(huán)中所有子組件實例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!