admin管理员组

文章数量:1396811

so I was programming an app with React and what happened is that I have a ponent with a fairly large list in its state. I am fetching a JSON file from network and then storing a filtered copy directly to ponent'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 ponent 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 ponentUpdates on every children and subchildren of the ponent 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 ponent 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 -> ponent -> 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 ponent with Vue just to see would it be better (which I think it would).

so I was programming an app with React and what happened is that I have a ponent with a fairly large list in its state. I am fetching a JSON file from network and then storing a filtered copy directly to ponent'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 ponent 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 ponentUpdates on every children and subchildren of the ponent 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 ponent 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 -> ponent -> 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 ponent with Vue just to see would it be better (which I think it would).

Share Improve this question asked Dec 15, 2017 at 13:12 TeemuKTeemuK 2,5811 gold badge23 silver badges19 bronze badges 7
  • 1 You could paginate the network response's results – Héctor Valls Commented Dec 15, 2017 at 13:14
  • @Héctor what do you mean? – TeemuK Commented Dec 15, 2017 at 13:18
  • Instead of work with, say, 5000 items at the same time, you could fetch the first 100 ones (for example), and include in your webapp some kind of pagination. So, in your state, there are just 100 items simultaneously and your filtering will be much faster – Héctor Valls Commented Dec 15, 2017 at 13:20
  • The biggest performance hit probably es when you render the list item values. You should consider only rendering the elements that will actually be in view with some sort of infinite scrolling as you go down. I think there is a package called react-list that does this. – Tyler Kirby Commented Dec 15, 2017 at 13:22
  • @JoeClay yep the original data is inside Redux reducer. And the list isn't actually that long, only 160 with some nested properties which is why this thing seemed so silly to me. I just to want to move on to more important things. If it helps and no one can e with a clear solution in couple days I'll make a code snippet or just link to the repo so anyone can see it for themselves. – TeemuK Commented Dec 15, 2017 at 13:23
 |  Show 2 more ments

1 Answer 1

Reset to default 4

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 ponents 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 ponent 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 es 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

本文标签: javascriptReact setState slowStack Overflow