You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中MUI Chip组件首次点击不渲染问题求助

问题解决:点击Add按钮后MUI Chip不立即显示的问题

问题原因

核心问题是状态更新未触发React重新渲染。在addWithSuffix函数中,你直接复用了原finalValue数组的引用(tempArray = finalValue只是复制引用而非创建新数组),随后将同一个引用传给setFinalValue。React通过对比状态引用判断是否需要更新,引用未变化时不会触发组件重渲染,因此Chip不会立即显示。只有修改Name或Suffix触发value状态更新时,组件才会重新渲染,此时新添加的Chip才会出现。

修复方案

修改addWithSuffix函数,通过创建新数组来更新状态,避免直接修改原数组:

const addWithSuffix = () => {
  const newItem = `${value.adnCharge} (${value.desgnSuffix})`;
  // 使用函数式更新确保拿到最新状态,同时创建新数组
  setFinalValue(prevFinalValue => [...prevFinalValue, newItem]);
}

也可以用concat方法创建新数组:

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

修改后的完整代码

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);
  }
  
  // 修复后的添加函数
  const addWithSuffix = () => {
    const newItem = `${value.adnCharge} (${value.desgnSuffix})`;
    setFinalValue(prevFinalValue => [...prevFinalValue, newItem]);
  } 

  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={addWithSuffix}>Add</button>
        <div>{finalValue.map((item, index)=><Chip key={index} label={item}/>)}</div>   
      </form>
    </>
  )
}

export default EditUsers

额外说明

使用函数式更新(setFinalValue(prevFinalValue => [...prevFinalValue, newItem]))是更稳妥的写法,它能确保你获取到最新的状态值,避免因React状态更新的异步特性导致的逻辑错误。

内容的提问来源于stack exchange,提问作者New Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:25:14