React中无需使用ref,如何将父元素g传入子元素rect的合成事件?
<g> Context to Child <rect> Without Refs Got it, let's tackle this since you're generating those <g> elements in a loop and want to avoid refs entirely. Here are two solid approaches:
Approach 1: Pass <g> Props Directly (Recommended)
Since you're looping to create <g> elements, you can store each <g>'s configuration in an array, then pass that config directly to the rectMouseDown handler when rendering the child <rect>. This keeps everything declarative and aligned with React's patterns.
Here's the modified code:
class MakeRotate extends React.Component { rectMouseDown = (e, gProps) => { // Now you can work with the parent <g>'s properties directly! console.log("Parent g transform:", gProps.transform); console.log("Parent g class:", gProps.className); // If you need to update the <g>'s properties, modify the state (or props) holding the configs // Example: this.setState(prev => update prev.gConfigs to change this <g>'s transform) } render() { // Replace this with your actual loop data (could come from props/state) const gConfigs = [ { className: "some-class", transform: "translate(40,40) rotate(0, 240, 80)" }, { className: "another-class", transform: "translate(100,100) rotate(0, 100, 50)" } // Add more <g> configurations here ]; return ( <div> {gConfigs.map((gProps, index) => ( <g key={index} {...gProps}> <rect x="0" y="0" width="60" height="60" onMouseDown={(e) => this.rectMouseDown(e, gProps)} /> </g> ))} </div> ) } }
Why this works:
- We store each
<g>'s attributes in a config array, so we can easily pass that data to the handler without touching the DOM. - Using
{...gProps}spreads the config into the<g>element, keeping your JSX clean. - This approach is stable even if your DOM structure changes later, unlike DOM traversal methods.
Approach 2: DOM Traversal (If You Need the Actual DOM Element)
If you specifically need access to the <g> DOM node (not just its props), you can use event bubbling to grab the parent element directly from the event object. Note: This depends on your DOM structure staying consistent, so use it cautiously.
class MakeRotate extends React.Component { rectMouseDown = (e) => { // Grab the parent <g> element from the event target's parent node const gDomElement = e.target.parentNode; // Now you can manipulate the DOM element directly console.log("Current rotate value:", gDomElement.transform.baseVal[0].angle); // Example: Update the transform attribute gDomElement.setAttribute("transform", "translate(40,40) rotate(45, 240, 80)"); } render() { // Your loop-generated <g> elements here, no extra props needed for the handler return ( <div> <g className="some-class" transform="translate(40,40) rotate(0, 240, 80)"> <rect x="0" y="0" width="60" height="60" onMouseDown={this.rectMouseDown} /> </g> {/* More looped <g> elements... */} </div> ) } }
Caveat:
- If you ever add another element between
<g>and<rect>(like a<circle>or<path>),e.target.parentNodewill point to that new element instead of<g>, breaking this logic. Stick with Approach 1 unless you absolutely need the raw DOM node.
内容的提问来源于stack exchange,提问作者Sourabh Banka

