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

React中如何给复用的Chart组件传不同props?useEffect逻辑处理求助

问题原因

你的问题核心是错误使用了全局DOM查询API:document.querySelector('.circle')会从整个HTML文档中匹配第一个类名为circle的元素,因此所有Chart组件的useEffect执行时,都只会修改第一个Chart组件内的圆环样式,最后一个组件的effect执行完毕后,自然就把前面的样式全部覆盖为最后一组props的值。而你写在return里的中心数值是直接绑定当前组件的props,每个组件的渲染上下文独立,所以显示正常。

解决方案

有两种常用的修复方式,推荐优先使用第二种:

方案1:用useRef绑定当前组件内的DOM元素

通过useRef锁定当前组件内部的circle元素,避免全局查询:

import { useEffect, useRef } from "react";
import "./chart.css";

const Chart = ({ color, number }) => {
  // 声明ref绑定内部的circle元素
  const circleRef = useRef(null);

  useEffect(() => {
    const circle = circleRef.current;
    if (circle) {
      circle.style.strokeDasharray = `${number} 100`;
      circle.style.stroke = color;
    }
  }, [color, number]);

  return (
    <div className="donut-chart">
      <svg viewBox="0 0 32 32">
        {/* 把ref绑定到当前组件的circle元素 */}
        <circle ref={circleRef} className="circle" r="16" cx="16" cy="16" />
      </svg>
      <div className="donut-center">
        <p className="centerNumber">{number}%</p>
      </div>
    </div>
  );
};

export default Chart;

方案2:直接用JSX内联样式绑定,无需手动操作DOM

完全符合React声明式渲染的写法,不需要操作DOM也不需要useEffect,更简洁不易出错:

import "./chart.css";

const Chart = ({ color, number }) => {
  return (
    <div className="donut-chart">
      <svg viewBox="0 0 32 32">
        <circle 
          className="circle" 
          r="16" 
          cx="16" 
          cy="16" 
          style={{
            strokeDasharray: `${number} 100`,
            stroke: color
          }}
        />
      </svg>
      <div className="donut-center">
        <p className="centerNumber">{number}%</p>
      </div>
    </div>
  );
};

export default Chart;

内容的提问来源于stack exchange,提问作者Alex Garzón

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:54:00