Чип-компонент 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.log(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
[LXI-SpartaCodingClub Full-Stack Bootcamp in Indonesia] 2023/1/21 TIL/Week 15]
[LXI-SpartaCodingClub Full-Stack Bootcamp in Indonesia] 2023/1/21 TIL/Week 15]
Я научился создавать карусель в ReactJS с помощью библиотеки Splide.
Краткое введение в Styled-компоненты
Краткое введение в Styled-компоненты
В настоящее время популярность Styled-компонентов становится все больше и больше. Большинство проектов, построенных на React.js, используют эту...
ДЕНЬ 8 | Страница обзора в React
ДЕНЬ 8 | Страница обзора в React
Сегодня я сделал страницу обзора с помощью react. Я использовал некоторые иконки из reacting icons и использовал генератор случайных чисел для...
Как настроить среду разработки React.
Как настроить среду разработки React.
весь процесс настройки среды разработки react.
Что вы должны знать о JSX - объяснение менее чем за 2 минуты
Что вы должны знать о JSX - объяснение менее чем за 2 минуты
React - это библиотека JavaScript для создания пользовательских интерфейсов.
Как использовать get bounds с react-leaflet и данными JSON
Как использовать get bounds с react-leaflet и данными JSON
Я считаю, что получить границы из библиотеки leaflet Js очень просто, но использование этой функции может быть немного сложным. Поэтому позвольте мне...
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.log(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

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