How to debounce search function in this React Component?

I have a component which gets a list of employees as a prop. I’ve also created an input element for filtering the list by string.
I moved filtering logic into a function which expects a list of data and a search value so it could return filtered list.

I want to add lodash debounce to search input, so whenever user types something, it would wait 1 second and filter the list out.

import React from 'react';
import _ from "lodash"

import { IEmployee } from '../../../store/EmployeesStore/reducer'

import AddEmployee from '../AddEmployee/AddEmployee';
import EmployeeItem from './EmployeeItem/EmployeeItem';

import { TextField } from '@material-ui/core';
import InputAdornment from '@material-ui/core/InputAdornment';
import SearchIcon from '@material-ui/icons/Search';

export interface EmployeeProps {
  employees: IEmployee[];
}

class EmployeeList extends React.Component<EmployeeProps> {
  state = {
    searchValue: ''
  };

//function which returns filtered list
  filterList = (employeesList: IEmployee[], searchValue: string) => { 

    return employeesList.filter((item: any) => {
      const fullName = `${item.firstName}${item.lastName}`.toLowerCase();
      const reversedFullName = `${item.lastName}${item.firstName}`.toLowerCase();
      const trimmedSearchValue = searchValue
        .replace(/\s+/g, '')
        .toLowerCase();
      return (
        fullName.includes(trimmedSearchValue) ||
        reversedFullName.includes(trimmedSearchValue)
      );
    });
  };

  render() {
    // saving filtered list data in filteredList variable
    let filteredList = this.filterList(this.props.employees, this.state.searchValue)
      
    return (
      <>
        <AddEmployee />
        <TextField
          style={{ marginLeft: '20px' }}
          size="medium"
          id="input-with-icon-textfield"
          variant="outlined"
          value={this.state.searchValue}
          onChange={(e) => this.setState({ searchValue: e.target.value })}
          InputProps={{
            endAdornment: (
              <InputAdornment position="end">
                <SearchIcon />
              </InputAdornment>
            ),
          }}
          InputLabelProps={{
            shrink: true,
          }}
        />
        <div>
          <ul
            style={{
              margin: '0px',
              padding: '0px',
              listStyle: 'none',
              display: 'flex',
              flexWrap: 'wrap',
            }}
          >
            {filteredList.map((employee) => {
              return <EmployeeItem key={employee.id} {...employee} />;
            })}
          </ul>
        </div>
      </>
    );
  }
}

export default EmployeeList;

Where should I add the _.debounce function and how?

1 thought on “How to debounce search function in this React Component?”

  1. You should not be calling your filterList function in return statement, instead of that it must be called on onChange of TextField.

    Something like this:

    handleChange = (e) => {
        this.setState({ searchValue: e.target.value })};
        const debouncedCall = _.debounce(() => this.filterList(this.props.employees, e.target.value), 1000);
        debouncedCall();    
    }
    
    //Rest of your code
    
    render() {
       <TextField
            onChange={(e) => handleChange(e)}
            ...other attributes
       />
    }
    
    Reply

Leave a Comment