Refinement list gets called multiple times.
I have created Custom Refinement component as follows. And below Component is rendered inside Parent component.
const RefinementList = ({
items,
isFromSearch,
refine,
attribute
}) => {
console.log('Inside Refinement list');
if(items.length === 0) {
return <h4> Sorry there are no refinemnets available. </h4>
}
return (
<ul className="check-list" style={{ listStyle: 'none' }}>
{
// Sort the items before rendering so it be in order everytime.
items &&
items
.sort(compareValues('label'))
.map(item => (
<li key={item.label} className="checkbox-cust">
<input
className="checkbox-in"
type="checkbox"
checked={item.isRefined}
style={{ fontWeight: item.isRefined ? 'bold' : '' }}
onChange={event => {
refine(item.value);
}}
/>
{isFromSearch ? (
<div>
<Highlight attribute="label" hit={item} />
</div>
) : (
<label htmlFor='checkbox-cust'>
<span>
{item.label} ({item.count})
</span>
</label>
)}
</li>
))}
</ul>
)
};
const CustomRefinementList = connectRefinementList(RefinementList);
export default CustomRefinementList;
The console.log() gets called 5-6 times, why does this happen?
I want to display message if items are empty for any attribute. What is happening is as this gets called many times the message Sorry there are no refinemnets available. gets displayed for a while and then actual refinements are rendered.
How this can be fixed?
Hi there, A react component can be rendered more than expected because of many reasons. But that's normal behavior of React and React diffs to render only changed parts.
If you want to display "no refinements" message in another way, you can wrap your RefinementList with Panel.
<Panel>
<RefinementList attribute="brand" />
<p className="no-refinements">No refinements</p>
</Panel>
.no-refinements {
display: none;
}
.ais-Panel--noRefinement .no-refinements {
display: block;
}
Panel will have "ais-Panel--noRefinement" className when its child RefinementList has no item. You can utilize the className to display/hide the message.
You can test the example here: https://codesandbox.io/s/empty-hooks-rod2b?file=/src/App.css:761-862
Let me know how it goes and if you have any question!
@eunjae-lee Thanks for the response.
But the message No refinements gets displayed on initial render for a while then refinement list is rendered.
This message should only be displayed if there are no refinements.
How can we do this?
Hi @abhirocks550 Sorry I didn't get your point.
When rendering the component before the search results arrive, the connector returns an empty array: https://github.com/algolia/react-instantsearch/blob/master/packages/react-instantsearch-core/src/connectors/connectRefinementList.js#L146:L146 and that's why you cannot distinguish between "no items" and "still loading". This should be nicer than this, but in the meantime you can workaround like the following example:
https://codesandbox.io/s/tender-khorana-356ij?file=/src/App.js:545-586
You can return null when !canRefine. Then you can avoid the flashing message.
In the above example when I enter invalid query for example vjdvjavvdfvjsdvfj I should see message
Sorry there are no refinemnets available.
But I am not getting the message.
Please find attached image for reference.

@abhirocks550 you're right. I didn't think of that.
So, you want to display nothing only in the first time where the initial search result hasn't arrived yet. Then, I guess you can have a variable outside to store whether or not you have the first search response.
https://codesandbox.io/s/charming-dubinsky-k7ryc?file=/src/App.js:423-677
Sorry it's not something you can do out of the box at the moment.
@eunjae-lee Thanks the above solution is working.
But having another issue.
When the page is initially loaded I have a Refinement list of Countries and when I Select country for example United States now in my component what I have is
{ this.state.selectedcountry && <RefinementList attribute={"states." + this.state.selectedcountry } /> }
It works fine on initial render but when I select country then I see the error message flashing then states of the country are displayed in refinement list.
Hi @abhirocks550, My example was just a PoC and is not covering all general purposes. So you need to adapt it to fit your needs. In my example, I manage only one variable hasFirstSearchResult, but in your case you should have some sort of a map to keep track of the flag per attribute, since you can have many attributes for this component.
I hope this helps.
Sure will work on this. Thanks.
It will be really helpful if library provides a way to identify if the data is still loading or request is completed.
Yes, we will discuss about the flag and try to find a way to provide it. Thanks for the feedback 👍
Hi! 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.
In React InstantSearch Hooks, you can retrieve search status easily with the useInstantSearch() Hook.