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

为映射对象设置独立状态值:解决Material UI Rating组件同值问题

问题描述

我基于映射对象构建了一个使用Material UI组件的星级评分组件,但点击任意星级评分时,所有评分都显示相同的值。如何让每个星级评分根据选择拥有独立的数值,使每个评分区域展示自身的对应值?

原代码

import * as React from "react";
import Rating from "@mui/material/Rating";
import Box from "@mui/material/Box";
import "./styles.css";

const data = [
  {
    id: 1,
    label: "Do you like"
  },
  {
    id: 2,
    label: "How do you use"
  },
  {
    id: 3,
    label: "Do you dislike"
  }
];

export default function HoverRating() {
  const [value, setValue] = React.useState(2);

  return (
    <Box sx={{ width: 200, alignItems: "center" }}>
      {data.map((rate, id) => ( 
        <div>
          <p>{rate.label}</p>
          <div className="rating">
            <Rating
              value={rate.value}
              max={10}
              onChange={(event, newValue) => {
                setValue(newValue);
              }}
            />
            <p>{value}</p>
          </div>
        </div>
      ))}
    </Box>
  );
}
解决方案

问题核心是你用了单个状态变量value存储所有评分的值,导致所有评分组件共用同一状态,点击任意一个都会同步更新所有显示。要实现独立控制,需要给每个评分项分配独立状态:

  1. 改用多状态存储:用对象保存每个评分项的对应值,以数据中的id作为区分键
  2. 绑定对应状态到组件:每个Rating组件的value绑定到对应id的状态值
  3. 精准更新状态:在onChange时仅更新当前评分项对应的状态值

修改后的代码:

import * as React from "react";
import Rating from "@mui/material/Rating";
import Box from "@mui/material/Box";
import "./styles.css";

const data = [
  {
    id: 1,
    label: "Do you like"
  },
  {
    id: 2,
    label: "How do you use"
  },
  {
    id: 3,
    label: "Do you dislike"
  }
];

export default function HoverRating() {
  // 初始化状态为对象,每个id对应初始值2
  const [values, setValues] = React.useState(
    data.reduce((acc, item) => ({ ...acc, [item.id]: 2 }), {})
  );

  return (
    <Box sx={{ width: 200, alignItems: "center" }}>
      {data.map((rate) => ( 
        <div key={rate.id}> {/* 添加唯一key,符合React列表渲染规范 */}
          <p>{rate.label}</p>
          <div className="rating">
            <Rating
              value={values[rate.id]}
              max={10}
              onChange={(event, newValue) => {
                // 更新对应id的状态值,保留其他项状态不变
                setValues(prev => ({ ...prev, [rate.id]: newValue }));
              }}
            />
            <p>{values[rate.id]}</p>
          </div>
        </div>
      ))}
    </Box>
  );
}

关键改动说明

  • 将单个value状态改为values对象,每个评分项的id作为键存储对应值
  • Rating组件的value改为values[rate.id],绑定到当前项的独立状态
  • onChange时使用函数式更新,仅修改当前id对应的状态值,不影响其他评分项
  • 给映射的div添加key={rate.id},避免React列表渲染警告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:28:37