开始做react了,遇到了第一个稍微复杂的问题。记录一下
背景
有多个模块,是动态新增的,模块内有校验,获取数据,需要通过父组件调用子组件的ref方法进行校验
核心是通过函数实时给ref赋值
return (
<input ref={(r)=>{
// 动态赋值
}} />
)
实时查看
代码
import { FC, forwardRef, useImperativeHandle, useState } from 'react';
// react ant design 是通过form自动收集,此处可以不传value和onChange
type InputCustomProps = {
value?: string;
onChange?: (x: InputCustomProps['value']) => void;
};
// 自定义输入框组件的ref接口
type InputCustomExposeHandle = {
validate: () => Promise<boolean>;
};
// 自定义输入框组件
export const InputCustom = forwardRef<InputCustomExposeHandle, InputCustomProps>(
({ value, onChange }, ref) => {
useImperativeHandle(ref, () => ({
validate: async () => {
return Math.random() > 0.5 ? true : false;
},
}));
return <input value={value} onChange={e => onChange?.(e.target.value)} />;
}
);
// 功能配置
const DynamicRefTest: FC = () => {
const mapRef = new Map<string, InputCustomExposeHandle>();
const [list, setList] = useState<Array<string>>([]);
return (
<div>
<button
onClick={() => {
setList([...list, '']);
}}>
新增
</button>
<button
onClick={async () => {
console.log(mapRef);
console.log(await mapRef.get('list-0')?.validate());
}}>
打印ref
</button>
{list.map((item, index) => (
<div key={index}>
<InputCustom
ref={r => {
return mapRef.set(`list-${index}`, r!);
}}
value={item}
onChange={value => {
console.log('value :>> ', value);
if (!value) return;
const _list = [...list];
_list[index] = value;
setList(_list);
}}
/>
<button
onClick={() => {
setList(list.filter((_, i) => i !== index));
}}>
删除
</button>
</div>
))}
</div>
);
};
export default DynamicRefTest;