[ad_1]
I have existing component called TextField. I would like to use this component as base to create NumberField component. Reason is I don’t want to type out exact same code when there are only minor tweaks in the NumberField component. There are 3 parts that I would like to change:
- For interface, TextField has
type="text" | 'search'
, but I would like to update it totype="text"
for NumberField component. - I would like to add new prop
inputMode="numeric"
for NumberField. - I would like to update
handleChange
function for onChange prop.
So I have coded up the following.
TextField.tsx
import React, { useState } from "react";
export interface ITextFieldProps {
type?: "text" | "search";
onChange?: (value: string) => void;
required?: boolean;
}
export const TextField: React.FunctionComponent<ITextFieldProps> = React.forwardRef<
HTMLInputElement, ITextFieldProps>((props, ref) => {
const { type = "text", onChange, required = true } = props;
const [value, setValue] = useState("");
function handleChange(e: React.FormEvent<HTMLInputElement>) {
setValue(e.currentTarget.value);
onChange?.(e.currentTarget.value);
}
return (
<input
type={type}
value={value}
onChange={handleChange}
required={required}
/>
);
});
NumberField.tsx
import React, { useState } from "react";
import { ITextFieldProps, TextField } from "./TextField";
export interface INumberFieldProps extends ITextFieldProps {
type?: "text";
inputMode?: "numeric";
}
export const NumberField: React.FunctionComponent<INumberFieldProps> = React.forwardRef<
HTMLInputElement, INumberFieldProps>((props, ref) => {
const { inputMode = "numeric", onChange } = props;
const [value, setValue] = useState("");
function handleChange(e: React.FormEvent<HTMLInputElement>) {
const updatedValue = e.currentTarget.value.replace(/\D/g, "");
setValue(updatedValue);
onChange?.(updatedValue);
}
return (
<TextField inputMode={inputMode} onChange={handleChange} value={value} />
);
});
App.tsx
import "./styles.css";
import { TextField } from "./TextField";
import { NumberField } from "./NumberField";
export default function App() {
function onChange(e: any) {
console.log(e);
}
return (
<div className="App">
<NumberField onChange={(e) => onChange(e)} />
</div>
);
}
With this code when I go to chrome dev tools and check input element, I only see <input type="text" />
, but I expect to see <input type="text" inputmode="numeric" />
, since I added inputMode prop. Also with regex in the handleChange function, I should be able to only type numbers in the input, but I get “Cannot read properties of undefined (reading ‘value’)” error. What’s the best way to solve this issue? Source: https://codesandbox.io/s/numberfield-component-ts-wohlok?file=/src/NumberField.tsx
[ad_2]