I have an app that render will multiple filters from two different components.
The initial state object goes something like this:
{
checkboxSelected: false,
dropdownSelected: false,
options_checkbox: [
{ title: "titleA",
options: [
{name: "name1", key: "key1", label: "label1", checked: false},
{name: "name2", key: "key2", label: "label2", checked: false},
{name: "name3", key: "key3", label: "label3", checked: false}
]
},
{
title: "titleB",
options: [
{name: "name4", key: "key4", label: "label4", checked: false},
.....
]
}
]
dropdownSelected: false,
key: "",
from: "",
to: "",
qf: false,
....
selectedFilters: [],
},
First, the Dropdown Component
, selects the key-value from the dropdown. As soon as the Apply
button is clicked, it creates an object with some properties and related key-value something like as defined in function:
// function called onClicking 'Apply'
const transferRanges = useCallback(() => {
const validation = validator();
if (!validation) return false;
//final object passed to the reducer.
const finalObj = {
dropdownSelected: true,
checkboxSelected: false,
from: state.identifiers_dropdown.from,
to: state.identifiers_dropdown.to,
individual: state.identifiers_dropdown.individual,
key: state.identifiers_dropdown.key,
fromToMode: state.identifiers_dropdown.fromToMode,
title: state.identifiers_dropdown.title,
qf: state.identifiers_dropdown.qf,
};
// updating the original state
dispatch({ type: "apply-dropdown", payload: state });
// creating array of objects of values selected from dropdown in a separate array state
dispatch({ type: "set-filters", payload: finalObj });
}, [state, validator, dispatch]);
Second, the Checkboxes Component
, allows to select muliple checkboxes. Just like the dropdown above, the checkboxes selected are also required to be passed as an object (keys of the selected checkboxes with some other properties) to the separate array state as already defined above:
dispatch({ type: "set-filters", payload: finalObj });
The state after a checkbox is selected:
{
checkboxSelected: true
options_checkbox: [
{ title: "titleA",
options: [
{name: "name1", key: "key1", label: "label1", checked: true},
{name: "name2", key: "key2", label: "label2", checked: false},
{name: "name3", key: "key3", label: "label3", checked: true}
]
},
{
title: "titleB",
options: [
{name: "name4", key: "key4", label: "label4", checked: false},
.....
]
}
],
......
}
I am using the useEffect()
call to check as soon as any checkbox is selected, it should filter out the selected checkboxes with property checked: true
.
useEffect(() => {
if (state.checkboxSelected) {
const selectedFiltersCheckbox = state.options_checkbox
.flatMap((o) => o.options)
.filter((o) => o.checked)
.map((o) => {
return {
key: o.key,
dropdownSelected: false,
checkboxSelected: true,
qf: false,
individual: "",
to: "",
from: "",
fromToMode: false,
};
});
console.log("checked boxes", selectedFiltersCheckbox);
dispatch({ type: "set-filters", payload: selectedFiltersCheckbox });
}
}, [state.identifiers_checkbox, state, dispatch]);
The reducer that updates the common array selectedFilters[]:
case "set-filters":
return {
...state,
selectedFilters: [...state.selectedFilters, action.payload],
};
The console.log("checked boxes", selectedFiltersCheckbox);
prints the result object/objects in format:
{key: "key1", dropdownSelected: false, checkboxSelected: true, apply: false, qf: false, …}
(if one checkbox selected) or
[
{key: "lot", dropdownSelected: false, checkboxSelected: true, apply: false, qf: false, …}
{key: "une", dropdownSelected: false, checkboxSelected: true, apply: false, qf: false, …},
]
(if more than one checkbox selected) perfectly.
Everything works fine in the case of 'Dropdown Component'. New object is added successfully to the array or being removed, but when passing same action dispatch({ type: "set-filters", payload: selectedFiltersCheckbox });
for checkbox, it runs into infine loop without adding the object to the final array.
I am unable to figure out how to resolve this. Stuck into this quite a while. Any help to get through this, will be really helpful.
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire