JSX属性禁用Lambda及TypeScript隐式any报错的解决方案咨询
解决JSX Lambda禁止和隐式Any类型的问题
我来帮你一步步搞定这两个问题,完全满足你不能修改Lambda规则的要求:
第一步:修复隐式Any类型报错
TypeScript抛出'values' implicitly has an 'any' type错误,是因为你没给values和arrayHelpers定义明确的类型。我们先从定义数据结构类型入手:
首先,明确单个设施和表单整体的类型:
// 单个设施的类型定义 type Amenity = { id: string; name: string; }; // 整个表单的values类型 type FormValues = { amenitieslist: Amenity[]; // 如果有其他表单字段,也可以在这里补充定义 };
然后给你的displayAmenities函数指定参数类型(结合react-hook-form的类型):
import { FieldArrayRenderProps } from 'react-hook-form'; const displayAmenities = ( values: FormValues, arrayHelpers: Pick<FieldArrayRenderProps, 'push' | 'remove'> ) => { // 你的渲染逻辑将在这里实现 };
这样TypeScript就能正确推断类型,不会再报隐式any的错误了。
第二步:替换JSX中的Lambda表达式
既然不能在JSX属性里直接写Lambda,我们可以把点击事件逻辑提取成组件内部的绑定方法,或者利用dataset传递索引,彻底避开Lambda:
方案1:组件内部绑定方法(简单直接)
假设你用的是函数组件,我们可以这样重构代码:
import { useForm, FieldArray, Field } from 'react-hook-form'; type Amenity = { id: string; name: string; }; type FormValues = { amenitieslist: Amenity[]; }; const YourFormComponent = () => { const { control, getValues } = useForm<FormValues>({ defaultValues: { amenitieslist: [] } }); // 提取添加设施的方法 const handleAddAmenity = () => { const arrayHelpers = control.getFieldArray('amenitieslist'); arrayHelpers.push({ id: "", name: "" }); }; // 提取移除设施的方法,通过dataset获取索引 const handleRemoveAmenity = (e: React.MouseEvent<HTMLButtonElement>) => { const index = parseInt(e.currentTarget.dataset.index || '0', 10); const arrayHelpers = control.getFieldArray('amenitieslist'); arrayHelpers.remove(index); }; // 渲染设施列表的逻辑 const renderAmenities = () => { const values = getValues(); if (!values.amenitieslist || values.amenitieslist.length === 0) { return ( <button type="button" onClick={handleAddAmenity}> Add an amenity </button> ); } return values.amenitieslist.map((_, index) => ( <div key={index}> <Field name={`amenitieslist.${index}.name`} /> <button type="button" onClick={handleRemoveAmenity} data-index={index} // 把索引存在按钮的dataset属性中 > - </button> </div> )); }; return ( <form> <FieldArray name="amenitieslist" render={() => <div>{renderAmenities()}</div>} /> <div> <button type="submit">Submit</button> </div> </form> ); };
方案2:抽分子组件+提前绑定方法(更优雅)
如果列表项逻辑复杂,你可以把单个设施项抽成子组件,并用useMemo提前绑定好每个索引的移除方法,彻底避免Lambda:
// 子组件:单个设施项 type AmenityItemProps = { index: number; onRemove: () => void; }; const AmenityItem = ({ index, onRemove }: AmenityItemProps) => { return ( <div> <Field name={`amenitieslist.${index}.name`} /> <button type="button" onClick={onRemove}> - </button> </div> ); }; // 父组件 const YourFormComponent = () => { const { control, getValues } = useForm<FormValues>({ defaultValues: { amenitieslist: [] } }); const values = getValues(); const arrayHelpers = control.getFieldArray('amenitieslist'); // 用useMemo提前生成绑定好索引的移除方法数组,避免每次渲染创建新函数 const removeMethods = React.useMemo(() => { return values.amenitieslist.map((_, idx) => () => arrayHelpers.remove(idx)); }, [values.amenitieslist, arrayHelpers]); const handleAddAmenity = () => { arrayHelpers.push({ id: "", name: "" }); }; const renderAmenities = () => { if (!values.amenitieslist || values.amenitieslist.length === 0) { return ( <button type="button" onClick={handleAddAmenity}> Add an amenity </button> ); } return values.amenitieslist.map((_, index) => ( <AmenityItem key={index} index={index} onRemove={removeMethods[index]} // 直接用提前绑定好的方法,无Lambda /> )); }; return ( <form> <FieldArray name="amenitieslist" render={() => <div>{renderAmenities()}</div>} /> <div> <button type="submit">Submit</button> </div> </form> ); };
这两种方案都能完全避开JSX属性中的Lambda,同时解决了TypeScript的类型报错问题,完全符合你的要求。
内容的提问来源于stack exchange,提问作者SaiBand
相关产品推荐
相关产品推荐

