Home > front end >  Strange issue with MUI/Material UI multiselect component
Strange issue with MUI/Material UI multiselect component

Time:01-02

this is my code : codesandbox multiselect demo

I need to extract unique items from an array based on id and display resulting array as options. I'm using MUI Select component.

It works when I use this to create the new array with distinct id value:

dictinctItems.push(item);

But this doesn't work for some reason.

dictinctItems.push({ id: item.id, label: item.label });

Whats wrong with the second form?

CodePudding user response:

Because when you do dictinctItems.push(item); you are pushing the reference of the same object into the list and when you do dictinctItems.push({ id: item.id, label: item.label }); you are pushing a new object every time.

In your component each time a new value is being selected you change the state in the handleChange which will trigger a re-render, this re-render will again run your getDistinctItemsById function at the top of the component and return a new list when you do dictinctItems.push({ id: item.id, label: item.label });.

This can be fixed if you use useMemo that is change

const dictinctItems = getDistinctItemsById(listData)

to

const dictinctItems = useMemo(() =>getDistinctItemsById(listData), [])

and you will always have the same objects on every re-render, no matter whether you use dictinctItems.push(item); or dictinctItems.push({ id: item.id, label: item.label });

Just to make to understand a bit more about copying reference and value in javascript

Just look at this example below

let stringValue = 'Hi';
const objValue = {id: "1", label: 'P1'};

// for primitive value, it copy gets pushed to array
const myArray = [];
myArray.push(stringValue);        // push copy of 'Hi' here
stringValue = 'Hi how are you';   // change 'Hi' to 'Hi how are you'
console.log(myArray[0]);          // myArray still contains 'Hi'

// for objects, its reference gets pushed
const newArray = [];
newArray.push(objValue);         // puts object reference into the array
objValue.id = "2";               // change 'id' property
console.log(newArray[0].id);     // here id will be changed to '2'    
  • Related