Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple unnecessary re-renders #33

Open
robwheatley opened this issue Jul 17, 2020 · 5 comments
Open

Multiple unnecessary re-renders #33

robwheatley opened this issue Jul 17, 2020 · 5 comments

Comments

@robwheatley
Copy link

Hi there,

Frist off - I'm loving Sortly. I'm making use of it in a Meteor app I'm hacking together as a prof of concept.

One thing I'm having a problem with though. My itemRenderer renders multiple times, even with no prop changes and I was wondering if you could help cast a little light on things....

I've tried to use React.memo with a custom equal function, but even with that, and equal props, I still get the problem (I noted that in one of your examples, you used Reac.memo, and I'm assuming the same problem exists in that too).

I think it all comes down to the hooks. I'm using useDrag and useDrop hooks. I think they always return different functions, and therefore cause a re-render. Not sure if they need to work like this or if there is some tweak I can make to prevent it. I'm not massively familiar with React or even Javascript (part of the reason I'm making my app is to learn).

Any thoughts?

@lytc
Copy link
Owner

lytc commented Jul 20, 2020

@robwheatley Could you post your replication code to somewhere like https://codesandbox.io/?

@robwheatley
Copy link
Author

@robwheatley Could you post your replication code to somewhere like https://codesandbox.io/?

Thanks for the reply - Bit tricky because the data is fed from a Mongo DB and I'm using Meteor, but I will see what I can do when I'm back from my holidays in a few days. Hopefully I can replicate with a simplified version. If nothing else, making a simplified version may help me ID the problem myself.

@robwheatley
Copy link
Author

@lytc Ah, I found a little time and knocked something together really quickly. It's a fork of your demo combined with a hack of one of your other demos. sandbox here

If you make a sort change and look at the console, you will see:
"Tree Rendered" when that renders (once to initialise and again for each onChange)
"container rendered: name" when each item container renders
"container the same? bool name" each time a container is asked to re-render

As you change the sort, you can see that all item containers are asked to re-render, and even though the memo areEqual function returns true (the bool in the list above) the container still re-renders. I don't think they should (maybe I have all this wrong). With more hacking by removing the useDrag and useDrop hooks, the re-renders go away.

I hope all of that makes sense to you...

@lytc
Copy link
Owner

lytc commented Jul 29, 2020

@robwheatley https://reactjs.org/docs/react-api.html#reactmemo

React.memo only checks for prop changes. If your function component wrapped in React.memo has a useState or useContext Hook in its implementation, it will still rerender when state or context change.

It rerender because of internal state change, isDragging for example!

@robwheatley
Copy link
Author

robwheatley commented Jul 29, 2020

But I wouldn't have thought that internal states would change on all items whenever they changed on one? I get that they would change on the one you are dragging and probably on the nearest neighbours too, but not on all the other items too. I must be missing something. Like I said in my intro, React and Javascript aren't my strongpoints.

My best guess at the moment is that the drag and drop (obtained from useDrag and useDrop) are functions and those functions are getting recreated each time something changes (a bit like when you do an in-line bind) forcing a re-render. Does that make any sense to you..?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants