Simon Long
Simon Long

Reputation: 1440

How to improve filtering for large array of React Elements?

I have a large number of React Elements in an array. When I type in an associated text field, the React elements get filtered depending on whether the text within each one contains the typed text or not.

Typing in the text field becomes sluggish when filtering a large number of elements like this. Presumably this is because everything is happening on a single thread and the filtering logic is hogging the thread while it is executing and thus slowing down UI input.

I'm presuming there must be a way to solve this in an asynchronous way in Javascript so the UI doesn't get blocked by background computational logic ?

I've been trying a couple of async-await based approaches found online but nothing has worked yet.

I've created a cut down Code Sandbox of my issue here :

Edit spring-dust-vbp9h

import React, { useState, useEffect } from "react";
import "./styles.css";
import { Button } from "@material-ui/core";

export default function MyFilterTextComponent(props) {
  const [filterText, setFilterText] = useState("");
  const [filteredElements, setFilteredElements] = useState(props.dataToFilter);
  const { dataToFilter } = props;

  useEffect(() => {
    setFilteredElements(
      dataToFilter.filter(currWord => {
        return currWord.includes(filterText);
      })
    );
  }, [dataToFilter, filterText]);

  const handleFilterTextChange = event => {
    setFilterText(event.target.value);
  };
  return (
    <div className="App">
      <label for="filterText">Filter text:</label>
      <input
        type="text"
        id="filterText"
        name="filterText"
        onChange={handleFilterTextChange}
      />
      <br />
      <br />
      {filteredElements.map(element => {
        return <Button>{element}</Button>;
      })}
    </div>
  );
}

Upvotes: 3

Views: 1888

Answers (1)

Drew Reese
Drew Reese

Reputation: 202781

Searching an array of words, checking if each word contains a search key is potentially an O(n^3) operation.

I tried throttling/debouncing the state update functions (i.e. only trigger setFilterText every 250ms and setFilteredElements every 500ms) but this doesn't really mitigate the O(n^3) search complexity, it only delays it. I did notice significant improvement when using a div/span (even a regular button) over the MUI Button though (even without throttling/debouncing). This implies a large overhead for the Material-UI Button component.

Edit filter array of words

Upvotes: 2

Related Questions