Issue with Mui Select not correctly displaying options from an array

I am attempting to utilize the MUI Select (with a chip) within a list, specifically with multiple selects based on certain data. It may be somewhat challenging to explain.

I have the capability to add or remove an individual select.

function SelectTest({}: Props) {
    const [selectArray, setSelectArray] = useState([{name: "Select 1", value: 1},{name: "Select 2", value: 2},{name: "Select 3", value: 3}])

  const handleAddSelect = () => {
    setSelectArray((prev) => {
    return [{name: "New select", value: 1}, ...prev];
   })
  }

  const handleDeleteSelect = (id: number) => {
    let temp = [...selectArray];
  
    console.log(id)
    temp.splice(id, 1);
    console.log(temp)
    setSelectArray(temp)
  }



  return (
    <Container
      sx={{
        display: "flex",
        flexDirection: "column",
        gap: 1,
      }}
    >
      <List>
        {selectArray.map((item, index) => (
            <SelectCard id={index} key={index} onDelete={handleDeleteSelect} value={item.value}/>
        ))}
      </List>
      <Button onClick={handleAddSelect}>Add Select</Button>
    </Container>
  )
}

export default SelectTest

And The Child Component

type Props = {
  onDelete: Function,
  id: number,
  value: number
};

const values = [
  {
    label: "Item 1",
    value: 1,
  },
  {
    label: "Item 2",
    value: 2,
  },
  {
    label: "Item 3",
    value: 3,
  },
  {
    label: "Item 4",
    value: 4,
  },
];

export default function SelectCard(props: Props) {
    const [item, setItem] = useState<number>(props.value)


    const handleItemChange = (event: SelectChangeEvent<typeof item>) => {
        const {
            target: { value },
          } = event;
          console.log(value);
          setItem(value as number);
    }


  return (
    <Card>
      <CardHeader
        title={"Select item " + props.id}
        sx={{
          backgroundColor: colorConfigs.sidebar.bg,
          color: colorConfigs.sidebar.color,
          display: "flex",
          justifyContent: "space-evenly",
        }}
        action={
          <IconButton
            onClick={() => {
              props.onDelete(props.id);
            }}
            sx={{
              color: colorConfigs.sidebar.color,
              alignSelf: "flex-end",
            }}
          >
            <DeleteOutline />
          </IconButton>
        }
      />
      <CardContent
        sx={{
          display: "flex",
          flexDirection: "row",
          gap: 1,
          pt: 2,
        }}
      >
        <FormControl
          sx={{
            flex: 1,
          }}
        >
          <InputLabel>{props.id}</InputLabel>
          <Select
            value={item}
            onChange={handleItemChange}
            input={
              <OutlinedInput
                label="Item"
              />
            }
          >
            {values.map((item, index) => (
              <MenuItem key={index} value={item.value}>
                {item.label}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </CardContent>
    </Card>
  );
}

I encounter strange behavior when adding an item, but I believe it is all connected. The primary issue arises when I "Delete" a select. In my actual application, I am elevating the state of the select's values and can observe that the correct values and objects are being deleted in the console. However, the rendered items still display the old values.

It appears to only remove the last item.

For instance, if I add 3 selects, assign different values to each (1 = 1, 2 = 2, 3 = 3), and then delete item 2, despite console messages indicating the correct deletion, visually I see 2 selects with the values of 1 = 1 and 2 = 2.

https://i.stack.imgur.com/6BEH6.png

https://i.stack.imgur.com/8iBrL.png

This is the console output after I "Delete" Select 2. While I clearly removed Select 2, the images above show that "Item 2" is still selected with its previous value, rather than expecting Item 3 to be displayed.

https://i.stack.imgur.com/blIrm.png

Answer №1

According to @RyanCogswell's suggestion, I decided to use the unique "name" of the object instead of a numerical index as the key for element array items. I believe that even a random value could serve this purpose effectively.

type Props = {}

function SelectTest({}: Props) {
    const [selectArray, setSelectArray] = useState([{name: "Select 1", value: 1},{name: "Select 2", value: 2},{name: "Select 3", value: 3}])

  const handleAddSelect = () => {
    setSelectArray((prev) => {
    return [{name: "New select", value: 1}, ...prev];
   })
  }

  const handleDeleteSelect = (id: number) => {
    let temp = [...selectArray];
  
    console.log(id)
    temp.splice(id, 1);
    console.log(temp)
    setSelectArray(temp)
  }



  return (
    <Container
      sx={{
        display: "flex",
        flexDirection: "column",
        gap: 1,
      }}
    >
      <List>
        {selectArray.map((item, index) => (
            <SelectCard id={index} key={item.name} onDelete={handleDeleteSelect} value={item.value}/>
        ))}
      </List>
      <Button onClick={handleAddSelect}>Add Select</Button>
    </Container>
  )
}

export default SelectTest

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with `styles` argument after updating from Material version 4 to 5: MUI

After recently upgrading from Material V4 to V5, I encountered the following error message: MUI: The `styles` argument provided is invalid. You are providing a function without a theme in the context. One of the parent elements needs to use a ThemeProvider ...

How to pass props to customize styles in MUI5 using TypeScript

Currently, I'm in the process of migrating my MUI4 code to MUI5. In my MUI4 implementation, I have: import { createStyles, makeStyles } from '@material-ui/core'; import { Theme } from '@material-ui/core/styles/createMuiTheme'; ty ...

Best practices for managing backend errors with Next.js 14

Currently, I am developing a project in Next.js 14 and I have set up my API requests using fetch within a handler.tsx file as shown below: async function getPositions() { const response = await fetch( process.env.BASE_API_URL + "/positions?enabl ...

Having difficulty viewing the options in the dropdown menu

For my current project, I am utilizing react for the frontend and django for the backend. Within my models, I have defined the following Role model: class Role(models.Model): ROLE_CHOICES = ( ('Recruiter', 'Recruiter'), ...

Can you explain the contrast between utilizing `next export` versus solely relying on React in your project?

After reading about the difference between next build && next export and next build && next start on this thread, I understand that the former generates a fully static app while the latter starts a server. This leads me to wonder, how does ...

Acquire keys from a different residence

Currently, I am working on a React component that accepts data through props and I aim to implement safe property access. I have experimented with the following: type Props = { items?: any[]; // uncertain about using type "any" bindValue?: keyof Prop ...

Error message: The 'Access-Control-Allow-Origin' policy is preventing access in a react express docker application

I have successfully set up a front-end React application and a Node/Express API using Docker. The React app is currently running on localhost:3000, while the API is running on localhost:9000. Both applications are fully functional. However, I am encounteri ...

What is the best way to create a Dialog with a see-through body in Android?

Is there a way to hide the background dialog box without hiding the inner content? Simply setting opacity to 0 won't work because it will also hide the children nodes: <Dialog title="Dialog With Actions" actions={actions} modal={no} ...

The GatsbyJS Link component comes with a border that mimics the appearance of being selected by tapping the TAB key

My observation is that the UP and DOWN arrow keys are used to move the selection, indicating that it may be tabbed into somehow. https://i.stack.imgur.com/NsNjQ.png I came across a material-ui Menu component where Gatsby Link components were wrapping the ...

What could be causing the issue with my Date and Time input not functioning correctly?

I developed a React frontend application styled with Material UI design. The issue I am facing is that after adding the Date and Time component styling to the form, it is unable to process the "name" value for posting. Specifically, the error message "Ty ...

Leveraging react-redux-firebase for integrating cloud functions into React JS applications

I recently started learning React JS and I'm working on a project where I need to display data from cloud firestore. To fetch the data, I am utilizing react-redux-firebase. It's all working smoothly so far. However, now I want to switch to retrie ...

Steps for incorporating HTML templates into a Next.js 13 project

Looking for advice on converting an HTML template using Bootstrap or Tailwind CSS into a Next.js 13.4 project. I have experience with Next.js 12 but understand that the project structure has changed, removing files like _app.js and _document.js. Any tips o ...

What is the best way to dynamically render and conceal multiple components upon clicking in JSX?

In my Class Component, I have incorporated 4 unique buttons. The expectation is that when a user clicks on any of these buttons, the corresponding Accordion Element should render. For example, if someone clicks on the summary button, the summaryAccordion w ...

Connecting to a fresh dynamic route does not impact the getInitialProps data

I am struggling to understand the difference between componentDidMount and getInitialProps. Despite my best efforts to research, I still can't figure out when to use each one in my specific case. Let me give you some context. I have a page called /co ...

Send properties to the makeStyles function and apply them in the CSS shorthand property of Material UI

When working with a button component, I pass props to customize its appearance: const StoreButton = ({ storeColor }) => { const borderBottom = `solid 3px ${storeColor}`; const classes = useStyles({ borderBottom }); return ( <Button varian ...

Stop Material UI Typography Text from exceeding the boundaries of its parent container

I am dealing with a situation where I have a Typography element nested inside a div, and the issue arises when the text within the Typography element is too lengthy causing it to overflow outside the boundaries of its parent div. This behavior is not desir ...

What is the best way to represent a state with two possible fields in React using TypeScript?

There is a specific state item that can have its own value or reference another item using an ID. interface Item { itemName: string; itemValue: { valLiteral: number } | { idNumber: string }; } const indItem1: Item = { itemName: "first sample&quo ...

Create a Material UI Text Field that has a type of datetime and can span multiple lines

Is it possible to create a Material UI component of type "datetime-local" that can be displayed on multiple lines while still allowing the date to be edited? The issue arises when the width is too narrow and cuts off the date text. Although the TextField ...

Encountering CORS issue while making Twitter API Fetch Request

I've been experimenting with incorporating the Twitter API into a React application that I'm currently developing. Utilizing the fetch API, I attempted to access the endpoint provided in the quick start guide at https://developer.twitter.com/en/d ...

Setting up Webpack with a Node.js backend

After successfully creating a structured outline for my React App, I have now uploaded the code to Github for easy access: https://github.com/KingOfCramers/React-App-Boilerplate. To launch this React server using Node and Express, I found a helpful guide ...