Topic: React Multiselect resets immediately after clicking check box (only if setting state)
Expected behavior
So I'm trying to allow my users to select from multiple roles they would like. I'd like to be able to store these roles in a state, so that I can submit them as part of another form in the same component all at once. However when I attempt to set state (in this case with setSelectedRoles, which is string[]) the multiselect quickly flicks off all the toggle options. The console log there correctly logs the selected options, but the selections are toggled off the state is also cleared.
const [selectedRoles, setSelectedRoles] = useState<string[]>([]); //above the return block
<MDBSelect
data={allRoles.map((value: RoleDTO, index: number) => {
return { text: value.name as string, value: index };
})}
multiple
label="Roles"
onValueChange={(e) => {
if (e instanceof Array){
setSelectedRoles(e.map((r) => r.text!));
}
console.log(JSON.stringify(selectedRoles));
}}
/>
Note that the options correctly stay checked if in the onValueChanged event I do not change state, however I need to capture the selected options somehow
Krzysztof Wilk staff answered 2 years ago
Hi!
You should wrap your data in the useMemo hook to memoize its value. So you can do:
const selectData = useMemo(() => selectedRoles.map((value: RoleDTO, index: number) =>{ return { text: value.name as string, value: index };}), [selectedRoles])
to prevent the Select component from rendering and pass this memoized variable to data
property :)
waiiki commented 2 years ago
That seems to have worked for the updating of the component. However logging "selectedRoles" now only returns an empty array.
const [selectedRoles, setSelectedRoles] = useState<string[]>([]);
let selectData = useMemo(() =>
allRoles.map((value: RoleDTO, index: number) =>{ return { text: value.name as string, value: index };}), [selectedRoles])
data={selectData} multiple label="Roles" onValueChange={(e) => {
console.log(JSON.stringify(selectedRoles));
}}
I have also tried replacing [selectedRoles] with [setSelectedRoles] and the same.
Is there another place I should be retrieving the selected role data from?
Edit: Removing: if (e instanceof Array){ setSelectedRoles(e.map((r) => r.text!)); } from onValueChanged is what allows the visuals of the component to work. However if I KEEP this line in here, the console.log correctly shows the clicked values but does NOT keep the component visuals updated. Everything is also immediately reset, including the selectedRoles state (even with memo) Its the same as the original post.
waiiki commented 2 years ago
Here is a pastebin of the full component. The MultiSelect is near the bottom
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Free
- Premium support: No
- Technology: MDB React
- MDB Version: MDB5 5.0.0
- Device: PC
- Browser: Chrome
- OS: Windows 10
- Provided sample code: No
- Provided link: No