3
votes

I am trying to implement custom input element for TextField component from Material UI

example :


export const InputsPage: React.FC = () => {
  const [value, setValue] = useState('');
  return (
    <Paper>
      <Box p={2}>
        <TextField
          value={value}
          onChange={(e) => {
            setValue(e.target.value);
          }}
          color='primary'
          label='FROM'
          placeholder='Placeholder'
          InputProps={{
            inputComponent: ({ inputRef, ...rest }) => <input ref={inputRef} {...rest} type='text' />,
          }}
        />
      </Box>
    </Paper>
  );
};

because i am using controlled input with my own state the input is not working properly ... each time ill trying to type some thing the input will loss focus so i need to type each char/number and make a click on the input again to make a focus so i can continue typing

if ill use uncontrolled input it will work properly

here is an example what is happening : codeSandbox

2

2 Answers

2
votes

The problem is that you are defining inline the component type for the inputComponent prop. This means that with each re-render it will be considered by React to be a new component type, so instead of just re-rendering, the element will be remounted (removed completely from the DOM and re-added) which results in focus being lost.

You can fix this by defining the component type (CustomInputComponent in the example) at the top-level as shown in the example below:

import React, { useState } from "react";
import "./styles.css";
import { TextField } from "@material-ui/core";
const CustomInputComponent = ({ inputRef, ...rest }) => (
  <input ref={inputRef} {...rest} type="text" />
);
export default function App() {
  const [value, setValue] = useState("");
  return (
    <div className="App">
      <TextField
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
        }}
        color="primary"
        label="FROM"
        placeholder="Placeholder"
        InputProps={{
          inputComponent: CustomInputComponent
        }}
      />
    </div>
  );
}

Edit custom input component

0
votes

A simple mistake done by you

just replace InputProps with inputProps

Codesandbox: https://codesandbox.io/s/intelligent-feather-4thqf?file=/src/App.js:423-433