Чип-компонент MUI в React не отображается при первом нажатии

Я использую MUI Select для опции множественного выбора и показываю окончательные значения после некоторой модификации в виде чипов MUI. Теперь, когда я нажимаю «Добавить», чип не отображается в этот момент, однако, если я изменяю какое-либо значение имени и суффикса, страница отображается, а затем отображается чип. Может быть, я что-то упускаю. Любая помощь приветствуется.

import { useState,  } from 'react';
import styled from 'styled-components';
import {OutlinedInput, MenuItem, Chip, useTheme, Select} from '@mui/material';

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250,
    },
  },
};

const EditUser =styled.div`
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-left:5px;
  margin-top: 10px;
  margin-bottom: 20px;
`
const Label = styled.label`
    width: 100px;
    margin: 10px;
`
const LabelInputWrapper = styled.div`
    margin-bottom:25px;
    flex:1 0 30%;
    display: ${(props) => props.disp};

`
const Adduserformcont = styled.div`
  display: flex;
  flex-wrap:wrap;
  margin:10px;
`
const AddChrgWrapper = styled.div`
    display: flex;
`

const names = [
  'Oliver Hansen',
  'Van Henry',
  'April Tucker',
  'Ralph Hubbard',
  'Omar Alexander',
  'Carlos Abbott',
  'Miriam Wagner',
  'Bradley Wilkerson',
  'Virginia Andrews',
  'Kelly Snyder',
];

function getStyles(name, personName, theme) {
  return {
    fontWeight:
      personName.indexOf(name) === -1
        ? theme.typography.fontWeightRegular
        : theme.typography.fontWeightMedium,
  };
}
const desigSuffix = ["I","II", "III", "IV"];

const EditUsers = () => {
  const theme = useTheme();
  const [personName, setPersonName] = useState([]);
  const [value, setValue] = useState({})
  const [finalValue, setFinalValue] =useState([])

  
  const onChangeUserForm = (event) => {
    if (event.target.name === 'selectMultiAddnCharg'){
      setPersonName(event.target.value)
    }
    let temp = {...value, [event.target.name]:event.target.value}
    setValue(temp);
    console.info(temp)
  
  }
  const addWithSuffix = () => {
    let tempArray = finalValue;
    tempArray.push(`${value.adnCharge} (${value.desgnSuffix})`)
    setFinalValue(tempArray)
    
  } 

  return (

    <>

    <form> 

        <AddChrgWrapper>
        <Label>Select name</Label>
        <Select
          name='selectMultiAddnCharg'
          multiple
          displayEmpty
          value = {personName}
          onChange = {onChangeUserForm}
          input = {<OutlinedInput />}
          renderValue = {(selected) => {
            if (selected.length === 0) {
              return <em>Select name</em>;
            }

            return selected.join(', ');
          }}
          MenuProps = {MenuProps}
          inputProps = {{ 'aria-label': 'Without label' }}
        >
          <MenuItem disabled value = "">
            <em>Placeholder</em>
          </MenuItem>
          {names.map((name) => (
            <MenuItem
              key = {name}
              value = {name}
              style = {getStyles(name, personName, theme)}
            >
              {name}
            </MenuItem>
          ))}
        </Select>
        </AddChrgWrapper>
      <LabelInputWrapper name = "adnCharge">
                <Label>Name</Label>
                <select name = "adnCharge" onChange = {onChangeUserForm}>                
                    <option>Select</option>
                    {personName.map((item,index) => <option key = {index}>{item}</option>)}
                </select>  
      </LabelInputWrapper>
      <LabelInputWrapper name = "desgnSuffix" >
                <Label>Suffix</Label>
                <select name = "desgnSuffix" onChange = {onChangeUserForm}>                
                    <option>Select</option>
                    {desigSuffix.map((item,index) => <option key = {index}>{item}</option>)}
                </select>  
      </LabelInputWrapper> 
      <button type = "button" onClick = {(e)=>addWithSuffix(e)}>Add</button>
      <div>{finalValue.map((item, index)=><Chip key = {index} label = {item}/>)}</div>   
      </form>
    </>
  )
}

export default EditUsers

Что вам нужно на выходе? Вы хотите иметь возможность просматривать фишки, когда выбрана опция множественного выбора? Пожалуйста, уточните подробнее. будем рады помочь

anurag-dhamala 19.11.2022 16:05

Я хочу просмотреть фишки, когда я нажимаю кнопку «Добавить».

New Coder 19.11.2022 16:24

Я могу просматривать чипы с вашим кодом без каких-либо изменений, если я изменю кнопку выбора «Имя» или «Суффикс». Если я только изменю multi-select , я все еще смогу просматривать чипы, но со значениями как «неопределенные». Это потому, что вы отображаете значения adnCharge и desgnSuffix в чипах, а не значение selectMultiAddnCharg.

anurag-dhamala 19.11.2022 16:31

После выбора одного имени и одного суффикса, а затем нажатия кнопки «Добавить» в первый раз, я должен иметь возможность просматривать чипы, но я их не вижу.

New Coder 20.11.2022 03:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
4
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В функции addWithSuffix, когда вы объявляете tempArray, это не новый массив, но вы все равно напрямую изменяете состояние finalValue, а это не разрешено. Из документов React:

state — это ссылка на состояние компонента во время применения изменения. Он не должен быть напрямую мутирован. Вместо этого изменения должны быть представлены путем создания нового объекта на основе входных данных из состояния.

Вы можете объявить новую переменную массива на основе старого состояния
let tempArray = [...finalValue]
или используйте первый аргумент setFinalValue, который является старым состоянием

const addWithSuffix = () => {
    let tempArray = [...finalValue];
    tempArray.push(`${value.adnCharge} (${value.desgnSuffix})`)
    setFinalValue(tempArray)
}

ИЛИ

const addWithSuffix = () => {
   setFinalValue(state => state.concat(`${value.adnCharge} (${value.desgnSuffix})`))
}

Демо:

const names = [
  'Oliver Hansen',
  'Van Henry',
  'April Tucker',
  'Ralph Hubbard',
  'Omar Alexander',
  'Carlos Abbott',
  'Miriam Wagner',
  'Bradley Wilkerson',
  'Virginia Andrews',
  'Kelly Snyder',
];

function getStyles(name, personName, theme) {
  return {
    fontWeight:
      personName.indexOf(name) === -1
        ? theme.typography.fontWeightRegular
        : theme.typography.fontWeightMedium,
  };
}
const desigSuffix = ["I","II", "III", "IV"];

const EditUsers = () => {
const { useState } = React
const { OutlinedInput, MenuItem, Chip, useTheme, Select } = MaterialUI;
  const theme = useTheme();
  const [personName, setPersonName] = useState([]);
  const [value, setValue] = useState({})
  const [finalValue, setFinalValue] =useState([])

  
  const onChangeUserForm = (event) => {
    if (event.target.name === 'selectMultiAddnCharg'){
      setPersonName(event.target.value)
    }
    let temp = {...value, [event.target.name]:event.target.value}
    setValue(temp);
    console.info(temp)
  
  }
  const addWithSuffix = () => {
    // let tempArray = finalValue;
    const newVal = `${value.adnCharge} (${value.desgnSuffix})`
    // tempArray.push(newVal)
    setFinalValue(state => state.concat(newVal))
  } 

  return (

    <>

    <form> 

        <div>
        <label>Select name</label>
        <Select
          name='selectMultiAddnCharg'
          multiple
          displayEmpty
          value = {personName}
          onChange = {onChangeUserForm}
          input = {<OutlinedInput />}
          renderValue = {(selected) => {
            if (selected.length === 0) {
              return <em>Select name</em>;
            }

            return selected.join(', ');
          }}

          inputProps = {{ 'aria-label': 'Without label' }}
        >
          <MenuItem disabled value = "">
            <em>Placeholder</em>
          </MenuItem>
          {names.map((name) => (
            <MenuItem
              key = {name}
              value = {name}
              style = {getStyles(name, personName, theme)}
            >
              {name}
            </MenuItem>
          ))}
        </Select>
        </div>
      <div name = "adnCharge">
                <label>Name</label>
                <select name = "adnCharge" onChange = {onChangeUserForm}>                
                    <option>Select</option>
                    {personName.map((item,index) => <option key = {index}>{item}</option>)}
                </select>  
      </div>
      <div name = "desgnSuffix" >
                <label>Suffix</label>
                <select name = "desgnSuffix" onChange = {onChangeUserForm}>                
                    <option>Select</option>
                    {desigSuffix.map((item,index) => <option key = {index}>{item}</option>)}
                </select>  
      </div> 
      <button type = "button" onClick = {(e)=>addWithSuffix(e)}>Add</button>
      <div>{finalValue.map((item, index)=><Chip key = {index} label = {item}/>)}</div>   
      </form>
    </>
  )
}
  
  const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<EditUsers />);
<!DOCTYPE html>
<html>
  <head>
    <script src = "https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
    <script src = "https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
    <script src = "https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src = "https://unpkg.com/@mui/material@latest/umd/material-ui.production.min.js"></script>
  </head>
  <body>

    <div id = "root"></div>

    <script type = "text/babel" src = "./script.js"></script>
  </body>
</html>

Большое спасибо за помощь. Можете ли вы немного объяснить, почему это не сработало и как изменение помогло?

New Coder 20.11.2022 11:28

Я обновил свой ответ. Надеюсь объяснение понятно.

Amr Eraky 20.11.2022 12:08

Другие вопросы по теме