How do I target DOM elements inside a react component, or should I avoid targeting DOM elements all together?
How do I target DOM elements inside a react component?
As per React's official docs, you can access the dom elements by using refs.
You have to create a ref by using the React.createRef()
call.
Should I avoid targeting DOM elements altogether?
Traversing the dom to fetch a particular dom element is not a good practice with React as it will cause a performance issue. However, react allows an alternative way to do the same by using createRef()
.
Can I make this functionality work without having to count the elements inside the render function and without having to use document.querySelectorAll?
Yes, consider the following steps to implement this:
Inside the constructor, create a ref for parentContainer like this:
this.ParentContainer=React.createRef();
Then use parentContainer ref in render:
<div onMouseMove={this._testFunction} id="ParentContainer"
ref={this.ParentContainer} >
Inside test component, use this.parentContainer as:
//replace this
//var spans = document.getElementById('ParentContainer').querySelectorAll('section');
//with this
var spans = this.parentContainer.current.childNodes;
You can check it here
EDIT
Any thoughts on how I can work around having to use the let counter inside the render function
You can define returnCustomProp
outside render like this:
(Here you will need to pass the index of each section instead of a this
reference)
returnCustomProp = (index)=> {
let x = 0;
if(this.state.customProperties[index]) {
x = this.state.customProperties[index].x;
}
let y = 0;
if(this.state.customProperties[index]) {
y = this.state.customProperties[index].y;
}
return "customProperty("+x+" "+y+")";
}
And use it with section like this:
<section custom={returnCustomProp(0)}>
<b>Custom content for part 1</b>
<i>Could be way different from all the other elements</i>
</section>
<section custom={returnCustomProp(1)}>
2
</section>
<section custom={returnCustomProp(2)}>
<div>
All content can differ internally so I'm unable to create a generic element and loop trough that
</div>
</section>
<section custom={returnCustomProp(3)}>
4
</section>
<section custom={returnCustomProp(4)}>
5
</section>
<section custom={returnCustomProp(5)}>
<div>
<b>
This is just test data, the actual data has no divs nested inside sections
</b>
<h1>
6
</h1>
</div>
</section>
<section custom={returnCustomProp(6)}>
7
</section>
<section custom={returnCustomProp(7)}>
8
</section>