Currnently, in TextField, I got onChange prop coded like this onChange={(e: React.FormEvent<HTMLInputElement>) => onChangeValue(e.currentTarget.value)}, but I would like to update to onChange={(e: React.FormEvent<HTMLInputElement>) => onChangeValue(e)} in NumberField so I used React.cloneElement to over-ride onChange prop. However, when I check the typeof e from onChangeValue function, I get string type, but I was expecting object since event is synthetic event. In TextField, I get object type for e. So why is in NumberField event is interpreted as string? Am I using cloneElement wrong way? https://codesandbox.io/s/over-ride-prop-type-mjw1sp?file=/src/NumberField.tsx
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, { useState } 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 }) => {
const [displayValue, setDisplayValue] = useState("");
const onChangeValue = (e: React.FormEvent<HTMLInputElement>) => {
if (typeof onChange === "function") {
console.log(typeof e); // string, but was expecting object
onChange(Number(e.currentTarget.value));
}
};
return (
<>
{React.cloneElement(<TextField value={displayValue} />, {
onChange: (e: React.FormEvent<HTMLInputElement>) => onChangeValue(e)
})}
</>
);
};
App.tsx
import React, { useState } from "react";
import { NumberField } from "./NumberField";
import "./styles.css";
export default function App() {
const [value, setValue] = useState(0);
return (
<div>
<NumberField value={value} onChange={(e) => setValue(e.target.value)} />
</div>
);
}