react-instantsearch
react-instantsearch copied to clipboard
Best practices for custom connector creation
Is your feature request related to a problem? Please describe 🙏
What are the best practices when creating a custom connector ?
Describe the solution you'd like 🤔
I would like to connect a Checkbox with connectToggleRefinement.js
but I want to have the refinement applied when checkbox is untoggled. It is a derived behavior of this issue #2963.
Describe alternatives you've considered ✨
I made a copy paste from the code of "connectToggleRefinement.js" and add a 'not' before 'checked' :
if (checked) {
nextSearchParameters = nextSearchParameters.addDisjunctiveFacetRefinement(
attribute,
value,
);
if (filter) {
nextSearchParameters = filter(nextSearchParameters);
}
}
Became :
if (!checked) {
nextSearchParameters = nextSearchParameters.addDisjunctiveFacetRefinement(
attribute,
value,
);
if (filter) {
nextSearchParameters = filter(nextSearchParameters);
}
}
Additional context
When doing copy paste, these imports annoy me as they are not available in "react-instantsearch-dom" module. I had to import the items directly from the dist.
import { find } from '../core/utils';
import createConnector from '../core/createConnector';
import {
cleanUpValue,
getIndexId,
getResults,
refineValue,
getCurrentRefinementValue,
} from '../core/indexUtils';
Became :
import { find } from 'react-instantsearch-core/dist/es/core/utils';
import { createConnector } from 'react-instantsearch-dom';
import {
cleanUpValue,
getIndexId,
getResults,
refineValue,
getCurrentRefinementValue,
} from 'react-instantsearch-core/dist/es/core/indexUtils';
Final note This does not seems to be a good approach for maintenance purpose because :
- Imports are ugly
- We have to to update the full code of the custom connector on each "react-instantsearch-dom" update
Do you have any tips or best practices about this situation ? Thanks in advance for your answers !
Yours faithfully, LCDP
Hi @LeComptoirDesPharmacies thank you for this feedback. Would it help if some of theses API were made public and exposed via react-instantsearch-core
?
Hi @tkrugg,
Yeah it would be a nice first step, avoiding to import directly the components from dist
folder !
There may be another thing that could help here : Connector options (passed to createConnector
) may be exported from the base connector.
Ex :
export const defaultOptions = {
displayName: 'AlgoliaToggle',
{...}
}
export default createConnector({
defaultOptions
});
Thus, if we need to override some aspects of the connector, it would be much easier / fine-grained. Ex :
import { connectToggleRefinement, connectToggleRefinementDefaultOptions} from 'react-instantsearch-dom'
const customizedOptions = {
...connectToggleRefinementDefaultOptions,
getSearchParameters: (searchParameters, props, searchState) => {
{...}
},
}
const connectCustomToggleRefinement = createConnector(customizedOptions);
However, we still need in our customized options some helpers functions that are only available in the base connector file. Ex : getCurrentRefinement
...
Yours faithfully, LCDP
cc @francoischalifour: do you think we can address some of theses issues in the next version?
The next version will use InstantSearch.js connectors where we use fewer internals, so it will be mostly solved.
We have a full guide on how to write a custom InstantSearch.js connector and use it to create a Hook or a widget in React InstantSearch Hooks: https://www.algolia.com/doc/guides/building-search-ui/widgets/create-your-own-widgets/react-hooks/
Since React InstantSearch Hooks will soon replace React InstantSearch v6, we'll probably not invest time in further documenting this for v6, so I'll go ahead and close this ticket.