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
相关产品推荐
相关产品推荐

