I have a parent component where I need to reuse a child component called Chart several times but with different props, but what happens is that the first component is the only one that is modified and also by the props of the last Chart component.
I understand that the center number is modified by the return of the component, but how can I do the logic inside the useEffect? I am new to React if someone could help me, thanks.
The code
const Dashboard = () => {
return (
<>
<div className="chartContainerMain">
<div className="chartsContainer">
<div className="chartContainer">
<p className="nameChart">chart 1</p>
<Chart color="red" number={45} /> ///// This is the component i need
to reuse
</div>
<div className="chartContainer">
<p className="nameChart">chart 2</p>
<Chart color="blue" number={90} /> ///// This is the component i
need to reuse
</div>
</div>
</div>
</>
);
};
export default Dashboard;
//-------- COMPONENT CHART CODE ---------------
import { useEffect } from "react";
import "./chart.css";
const Chart = ({ color, number }) => {
useEffect(() => {
let circle = document.querySelector(".circle");
circle.style.strokeDasharray = `${number} 100`;
circle.style.stroke = `${color}`;
}, [color, number]);
return (
<>
<div className="donut-chart">
<svg viewBox="0 0 32 32">
<circle className="circle" r="16" cx="16" cy="16" />
</svg>
<div className="donut-center">
<p className="centerNumber">{number}%</p>
</div>
</div>
</>
);
};
export default Chart;
You can see this image
https://i.stack.imgur.com/762F6.png
CodePudding user response:
The problem you're running into likely has to do with the fact that you're trying to use the <Chart />
component to modify a DOM node (document.querySelector(".circle")
) directly, especially since document.querySelector(".circle")
will return the first element it finds. Instead your <Chart />
component itself should render that node and apply whatever styles you need to it based on the props. You probably don't need the useEffect
hook at all...
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;
I'm not too sure what the exact problem you're running into is, but based on your question and code sample, hopefully this helps, or at least points you in the right direction.
CodePudding user response:
The easiest way you can use the props coming from parent in your case is to directly inject them into the inline style of the <cirlce style={{ strokeDasharray: `${number}, 100`, stroke: color }} />
element and remove the useEffect
completely.
You can check the documentation for styling in react https://reactjs.org/docs/dom-elements.html#style