使用React.cloneElement覆写组件Prop类型时遇类型错误求助
问题分析与修正方案
错误点1:NumberField中e.currentTarget.value类型不匹配
TextField的onChange回调接收的是string类型的value,而非事件对象。你给TextField传的onChange函数错误地使用了事件对象作为参数,同时e.currentTarget.value是string类型,无法直接传给需要number的onChangeValue。
错误点2:App.tsx中e.target.value不存在
NumberField定义的onChange回调接收的是number类型的值,而非事件对象,所以App里的回调参数不是事件,自然没有target.value属性。
错误点3:NumberField内部state未与props同步
你在NumberField里维护了numberValue,但没有关联传入的value props,导致组件无法响应父组件的value变化。
修正后的代码
TextField.tsx(无需修改)
import React from "react"; import "./styles.css"; export interface ITextField { onChange?: (value: string) => void; value?: string; } export const TextField: React.FC<ITextField> = ({ value = "", onChange }) => { const onChangeValue = (value: string) => { if (typeof onChange === "function") { onChange(value); } }; return ( <div> <input type="text" value={value} onChange={(e: React.FormEvent<HTMLInputElement>) => onChangeValue(e.currentTarget.value) } /> </div> ); };
NumberField.tsx(核心修正)
import React from "react"; import "./styles.css"; import { TextField, ITextField } from "./TextField"; export interface INumberField extends Omit<ITextField, "onChange" | "value"> { onChange?: (value: number) => void; value: number; formatOnType?: boolean; } export const NumberField: React.FC<INumberField> = ({ value, onChange }) => { // 将number转成string传给TextField const textValue = value.toString(); // 处理TextField的string输入,转成number后传递给父组件 const handleTextChange = (textValue: string) => { // 过滤非数字字符,转成number const numValue = textValue ? Number(textValue.replace(/[^0-9]/g, "")) : 0; onChange?.(numValue); }; return ( <TextField value={textValue} onChange={handleTextChange} /> ); };
说明:这里直接使用
TextField组件而非React.cloneElement,更简洁且类型更安全;同时处理了字符串转数字的逻辑,过滤非数字字符避免转换失败。
App.tsx(修正onChange回调)
import React, { useState } from "react"; import { NumberField } from "./NumberField"; import "./styles.css"; export default function App() { const [value, setValue] = useState(0); return ( <div> {/* onChange接收的是number类型的值,直接赋值即可 */} <NumberField value={value} onChange={(num) => setValue(num)} /> </div> ); }
内容的提问来源于stack exchange,提问作者Judoboy Alex
相关产品推荐
相关产品推荐

