Prevent re-render when not necessary
Feature: What is your use case for such a feature?
Don't re-render components when props + state don't change.
Feature: What is your proposed API entry? The new option to add? What is the behavior?
Use PureComponent for the components & returned widgets after being connected?
What is the version you are using? Always use the latest one before opening a bug issue.
5.1.0
Every component is re-rendered, every time. https://github.com/maicki/why-did-you-update makes this visible.
Thanks for your time!
This could be a bug OR feature 😄
We already have a shouldComponentUpdate hook inside the function that creates the connector. Indeed the "view" components don't use shouldComponentUpdate or PureComponent. The latter won't avoid extra renders because most of the time props are not shallow equal. Most of the time it's completely fine to let React do the render.
Do you have any performance issue with React InstantSearch? If so please give us a reproducible example, it will help us to better understand where the issue come from. We provide template to avoid you the boilerplate part. You can find it on CodeSandbox.
Our use case is wrapping a Google maps component with the HitsConnector rendering the maps component alongside a location list component. The re-render is causing a flicker in the maps view even when the filtered list doesn't change. There's no state change in the controlling component to necessitate a re-render which led me down the path of the aforementioned utility to investigate.
Any ideas? Doing a deep comparison of props(hits) in shouldComponentUpdate? Thanks for the response!
Yes a possible solution is to implement a deep comparison inside shouldComponentUpdate. Is it possible to give us a small example of what you are trying to do? It will be easier to give you a more suitable solution. You can find a template on CodeSandbox. Thanks!
I think I've stumbled across this too - would you still like a test reproduction?
For anyone that runs into this - I removed 3 needless render() calls with the following:
// customHits.js
shouldComponentUpdate(nextProps) {
if (this.props.hits.length !== nextProps.hits.length) {
return true;
}
for (let i = 0; i < nextProps.hits.length; i++) {
if (nextProps.hits[i].objectID !== this.props.hits[i].objectID) {
return true;
}
}
return false;
}
You can do the same thing with a functional component using React.memo().
const AlgoliaHitsLoaderCached = React.memo(AlgoliaHitsLoader, (prevProps, nextProps) => {
if (prevProps.hitsNeedLoading.length !== nextProps.hitsNeedLoading.length) {
return false;
}
for (let i = 0; i < nextProps.hitsNeedLoading.length; i++) {
if (nextProps.hitsNeedLoading[i].objectID !== prevProps.hitsNeedLoading[i].objectID) {
return false;
}
}
return true;
});
Note, my prop is based around hitsNeedsLoading as my component was loading additional information from the server based on the returned hits from algolia.
When I pass a function as a props to connectHits it causes a one extra request to the instant search server, can anyone suggest the solution?
Hey!
We're doing a round of cleanup before migrating this repository to the new InstantSearch monorepo. This issue seems not to have generated much activity lately, so we're going to close it.
You can use this React InstantSearch Hooks template as a base for creating a Geo search experience.
Now, as described in the docs, when you provide a function to Hooks, you need to provide a stable reference to avoid rendering endlessly.
We recommend anyone who is currently using React InstantSearch v6 to migrate to Hooks.