Hi I have the below code, in which I am trying to get the value inside list using when a person clicks on the button wrapped inside that is inside list element. I tried using UseRef but it is returning all the listed items, but In my case I only want to target the value that is associated with that button. Here is my current approach.
const tabRef = useRef();
function addButtonHandler() {
console.log(tabRef.current.innerText);
}
<ul ref={tabRef}>
<li >
<button onClick={addButtonHandler}></button>
Some context here.</li>
<li >
<button onClick={addButtonHandler}"></button>
More context here.</li>
<li >
<button onClick={addButtonHandler}></button>
even more context here.</li>
</ul>
CodePudding user response:
This seems like a good candidate for event delegation. Also, you don't necessarily need a ref here just to get the value, because JavaScript event handlers provide you with the event
object, which includes the target
of the event! You could certainly use a ref to store it for later, but my point here is that useRef
is not a necessary part of getting a value from a list in an event handler. No "Reacty" features needed at all here!
const App = () => {
function handleClick(event) {
event.preventDefault();
if (event.target.tagName === 'BUTTON') {
console.log(event.target.nextSibling);
}
}
return (
<ul onClick={handleClick}>
<li>
<button>Button 1</button>
<span>Some context here.</span>
</li>
<li>
<button>Button 2</button>
<span>More context here.</span>
</li>
<li >
<button>Button 3</button>
<span>even more context here.</span>
</li>
</ul>)
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>
CodePudding user response:
You may get DOM nodes of those <li>
s by looking at tabRef.current.children[n]
But not sure if ref is the right way in React to achieve what you wanted to do. How about to hold the text within an array?
const textArr = ['Some context here', 'More context here', 'even more context here'];
const addButtonHandler = (text) => { console.log(text) };
return (<ul>
{ textArr.map(text =>
<li key={text}><button onClick={() => addButtonHandler(text)} />{text}</li>) }
</ul>)