Codementor Events

Enhance your input fields with wait logic

Published Feb 11, 2021
Enhance your input fields with wait logic

Input fields that wait for a user to finish typing before performing an action are common feature in web applications. They can be tricky to get working so I wanted to show how I incorporated a wait timer into my input fields.

In my case, I needed a field that waits for users to finish typing in a few places. I already had an input component made with some custom styling, so I decided to extend the wait logic as a customizable feature.

For my example, Im using React, Typescript and Material UI.

Below is the complete example, I'll step through the component piece by piece for the rest of the article.

example

interface IProps extends OutlinedTextFieldProps {  
  waitForInput: boolean
}

Here I'm defining an interface with a custom property that extends the type used by Material UI Outlined Text Field component. This way I can use the component the same way I normally would, it just has one extra property.

const { waitForInput, ...inputProps } = props

You'll get a console warning if you add an unknown property to a Material UI component, so I separate my custom property from the outlined text field ones.

const [waitEvent, setWaitEvent] = useState<React.ChangeEvent<HTMLInputElement>>(null)

This is where I store the text field onChange event while we wait for the user to stop typing.

useEffect(() => {
  let timer = 0
  if (waitEvent && waitForInput) {
    timer = setTimeout(() => inputProps.onChange(waitEvent), 1000)
  }
  return () => clearTimeout(timer)
}, [waitEvent])

I leverage useEffect to handle my wait logic. It will rerun every time waitEvent is updated. If waitEvent and waitForInput are truthy, each change will reset the timeout to wait for 1 second.

const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  if (waitForInput) {
    event.persist() <- only for React 16 and earlier
    setWaitEvent(event)
  } else {
    inputProps.onChange(event)
  }
}

Replacement for the standard onChange function. Adds a check for if we should use the wait logic or continue as normal.

return <TextField {...inputProps} onChange={onChange} />

return the standard Material UI text field component while spreading out all our properties. The onChange assignment should come after the spread of inputProps.

<ExtendedInput
  waitForInput
  variant="outlined"
  label="Extended Input"
  onChange={(e) => alert(e.target.value)}
/>

Now you can use the component exactly as you would if it was the original Material UI version. With the added waitForInput property available.

Discover and read more posts from Jesse Langford
get started
post commentsBe the first to share your opinion
Ferran Buireu
3 years ago

Thanks, Jesse! It’s a very specific use-case but it’s really useful (similar to using debounce). Thanks for the insights. I guess for the most “common” cases maybe the onBlur built-in event is more suitable.

Jesse Langford
3 years ago

Yeah if this was a vanilla application I would have used onBlur.

Show more replies