Reputation: 1440
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 :
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
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.
Upvotes: 2