I'm working on a search results filter which is controlled by clicking on a button, opening a dropdown menu, selecting checkboxes for each filter, and clicking on an "Apply" button. I'm trying to get this button to change the href on click, but it seems to be a step behind. In my experience, when this issue of being a step behind comes up, it usually has something to do with the state management.
I'm able to see that selected (which is the chosen filters) updates correctly. But when logging the href, it's always a bit behind. Could this be because there's no dependency for href in my useEffect?
Example: user selects the "document" filter from the dropdown menu and clicks "Apply". After clicking, they see ['documentType'] in the logs for selected. But for the href log, they see ?. Then the user selects the "folder" filter in addition to the previous selection aand selected is logged as ['documentType, 'folderType'] and href is logged as ?types=pdf.
const translatedTypesArray = [
['document', 'documentType'],
['folder', 'folderType'],
['image', 'imageType'],
];
type Props = {
getBaseHref: (overrides: Object) => string,
types: string,
};
const SearchFilterType = ({ getBaseHref, types }: Props) => {
const typesArray = types ? types.split(',') : [];
const [selected, setSelected] = React.useState(typesArray);
const [href, setHref] = React.useState('#');
const getHref = () => {
const typesFilters = [];
translatedTypesArray.forEach(([type, translationID]) => {
const isSelected = selected.includes(translationID);
if (isSelected) {
typesFilters.push(type);
}
});
return getBaseHref({ types: typesFilters.join(',') || undefined });
};
React.useEffect(() => {
// this shows which filter item is selected
console.log(selected);
const selectedHref = getHref();
setHref(selectedHref);
// this shows the href after calling the setter, but it's always one step
// behind here
console.log(href);
}, [selected]);
const handleOnApply = (event: any) => {
setSelected(event);
};
return (
<RouterLink href={href}>
<ItemTypeSelectorQuickFilter onApply={e => handleOnApply(e)} selected={selected} />
</RouterLink>
);
};
export default SearchFilterType;