Reputation: 67
This is my code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
const [point, setPoint] = useState(null);
function handleClick(e) {
document.querySelector("#politscale").querySelectorAll("span").forEach(s => { s.style.backgroundColor = "grey"; })
e.target.style.backgroundColor = "red";
console.log(document.querySelector("#politscale").querySelectorAll("span"))
setPoint( Array.prototype.indexOf.call(document.querySelector("#politscale").querySelectorAll("span"), e.target))
cogoToast.success(point)
console.log(point)
}
useEffect(() => {
document.querySelector("#politscale").querySelectorAll("span").forEach(s => {
s.addEventListener("click", handleClick)
})
}, [])
I have such a scale bar and I want to find the index of clicked element out of all other children in the parent element, so I can send it to backend later on:
<Scale id="politscale">
<span id="scaleControlUnit"></span>
<span id="scaleControlUnit"></span>
<span id="scaleControlUnit"></span>
<span id="scaleControlUnit"></span>
<span id="scaleControlUnit"></span>
</Scale>
Upvotes: 0
Views: 89
Reputation: 63579
React is a framework that is state-based - the state informs the render of the DOM. Trying to use querySelector and its equivalent won't work like you think it will.
So here's an example of this working.
We set the state to be the index of the span (initially nothing).
handleClick
which is attached to the div
(or would be attached to your Scale
element) grabs the data id attribute from the span and adds it to the state.
This triggers the page to re-render, the spans get rebuilt, and depending on the state the selected
class gets added.
There is no other DOM manipulation going on. React does all that heavy lifting for you.
// Get a hook function
const {useState} = React;
function Example() {
// Set up state. You want to be saving the
// index of the span you've selected
const [index, setIndex] = useState();
// handleClick takes the id of the span and
// sets it to state (as a number, not a string)
function handleClick(e) {
const { target: { dataset: { id } } } = e;
setIndex(+id);
}
// getSpans just creates the spans but
// uses the state to identify which one should be selected
function getSpans() {
const arr = [];
for (let i = 0; i < 4; i++) {
arr.push(
<span className={index === i && 'selected'} data-id={i}>{i}</span>
)
}
return arr;
}
return (
<div onClick={handleClick}>
{getSpans()}
</div>
);
};
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
span { background-color: grey; padding: 1em;}
.selected { background-color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 1