TeemuK
TeemuK

Reputation: 2539

React setState slow

so I was programming an app with React and what happened is that I have a component with a fairly large list in its state. I am fetching a JSON file from network and then storing a filtered copy directly to component's state. Might be unoptimal solution BUT I think that's still okay and React should handle it I mean, it's just 10 kB.

Anyway I decided to add a search input to my component and store its value to its state. Now I have both the large list and searchInput in its state which I am setStating every onChange and filtering the list based on that.

And that is super slow. Every setState is refreshing the list and doing componentUpdates on every children and subchildren of the component which basically makes the search unusable.

So my question is how to fix this issue? Should I store the filtered list in the redux store instead of local component state? That doesn't seem that good a solution either as I have now a global searchInput value which I have to reset and delete on leave and which I think is better as local value.

Here's how it's currently:

list -> component -> filter list -> child -> split the list into 4 -> subchild -> map the sublist -> render the list item values

What I thought too was adding additional list with values showing which items should be hidden/shown so instead of manipulating the large list I am manipulating smaller list of item ids. Still that seems a bit silly, this thing shouldn't be this hard I mean people have been doing lists with JS and HTML quite a while now. I was thinking about re-creating the same component with Vue just to see would it be better (which I think it would).

Upvotes: 4

Views: 14642

Answers (1)

João Cunha
João Cunha

Reputation: 10307

I see your problem. It's not actually the setState that is slow but actually the rendering and the way you search things in said state.

If I were you I would invest time in 2 things:

  1. debounce for the searching

debounce doesn't trigger the search immediately but "waits" a set amount of time for the user to stop typing and then it triggers the function.

Here's an example in React:

// you can use another one. I've just used this one before and it works
import debounce from "throttle-debounce";

class SearchBox extends React.Component {
    constructor(props) {
        super(props);
        // "waits" for 750 ms
        this.search = debounce(this.search, 750);
    }

    search() { ... }

    render() {
      <input type="text" onKeyUp={this.search} />
    }
}
  1. If you have a big list then memoization is a good bet. You can use react-virtualized for that.

React components for efficiently rendering large lists and tabular data

You can even access the List demo here

  1. A good UI design and pagination

react-virtualized List component will only render what is being seen by the user. So if you have a nice UI design you can juice up a lot of performance from a really big list of values.

Many times it comes down to how you display data to your end-users. So you can add pagination to your data and fetch more either with pagination links or a infinite scroll feature.

Hope I helped

Upvotes: 4

Related Questions