I've got an SVG with hundreds of <circle>
elements that I would like to attach a click event to. Using jQuery, that's really easy:
$('circle').on('click', function(e) {
alert('clicked');
});
How can I do this in React?
Normally I would attach an event listener to the element directly:
<circle onClick={(e) => handleClick()} />
Seeing as there are hundreds of elements, this would be very tedious. Is there a way I can attach a single event listener to all circle elements?
My working solution uses vanilla JS, but it involves interacting with the DOM directly:
useEffect(() => {
const circles = document.querySelectorAll('circle');
for (const trigger of circles) {
trigger.addEventListener('click', (e) => {
alert('clicked');
});
}
}, []);
I don't get any errors and this does work, but it doesn't feel like React. Am I missing something? Is there a better approach?
I don't think you should worry for with vanilla JS DOM manipulation in such cases, but if you want to make it react-ish you can use Context.
First define your context:
const CircleContext = React.createContext();
then wrap your app (or part of app where circles will be used) with CircleContext.Provider
and set it's value to desired callback:
function App() {
return (
<CircleContext.Provider
value={e => {
console.log("Circle clicked!");
}}
>
<div className="App">
<Circle />
</div>
</CircleContext.Provider>
);
}
And consume that context in your circle component (I used useContext
hook):
function Circle() {
const context = useContext(CircleContext);
return <button onClick={context}>My Button</button>;
}
With this implementation every Circle
component will use same onClick
handler defined in CircleContext.Provider
.
Example code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With