Krzysztof Żuraw blog

Debouncing forms in React with Redux - part one

February 10, 2018

Hi! Today I want to start a new blog post series. This one will be all about debouncing react forms. Let’s get started!

Basic react form

Before we jump into debouncing and what it means I want to present you a simple react form. It looks like this:

image

I made this using awesome Tailwind CSS. The code for this form sits mainly in two components - App.js:

class App extends Component {
  constructor(props) {
    super(props)
    this.state = { typedWords: [] }
  }

  handleChange = event => {
    const { value } = event.target
    let typedWords = [...this.state.typedWords, value]
    this.setState({ typedWords })
  }
  render() {
    return (
      <div className="flex flex-col items-center min-h-screen w-full bg-teal-lighter bg-repeat">
        <div className="container md:max-w-sm md:mx-auto">
          <h1 className="block w-full text-center text-grey-darkest mb-6">
            Debounce in React
          </h1>
          <SearchInput handleChange={this.handleChange} />
        </div>
        {this.state.typedWords.map((word, key) => (
          <SearchResult text={word} key={key} />
        ))}
      </div>
    )
  }
}

and SearchInput:

class SearchInput extends Component {
  render() {
    const { handleChange } = this.props
    return (
      <form className="mb-4" onChange={handleChange}>
        <div className="flex flex-col mb-4 md:w-full">
          <label
            className="mb-2 uppercase font-bold text-lg text-grey-darkest"
            htmlFor="search-input"
          >
            Search input:
          </label>
          <input className="field" name="search" type="text" id="search" />
        </div>
      </form>
    )
  }
}

How it works

In my App component I define a handleChange function which then will be used inside SearchInput as a callback. In handleChange, I extract typed character from html input. Then I make a copy of state and insert a new value from SearchInput component.

SearchInput is representing html form so I treat it as a representational component.

You may notice another component - SearchResult which looks like this:

function SearchResult(props) {
  const { text } = props
  return (
    <div className="container md:max-w-sm md:mx-auto">
      <span>{text}</span>
    </div>
  )
}

it is still only representing html.

I have my components working so let’s type something into a search input:

Form without debouncing from Noaal on Vimeo.

Whoa! What is happening here?

onChange event handler fired up every time I typed something into an input. That’s not exactly what I wanted - I want my handler to capture only full typed words. How to do it?

By using debouncing - which I will explain in next blog post! Stay tuned and thanks for reading.


Want to get blog posts via email?

Powered by Buttondown.


Krzysztof Żuraw

Written by Krzysztof Żuraw who lives and works in Wrocław. About page.