To demonstrate my question, I'll compare vanilla javascript and react. In javascript, when I have
<div>
<button class="btn">1</button>
<button class="btn">2</button>
<button class="btn">3</button>
<button class="btn">4</button>
<button class="btn">5</button>
</div>
and I want to add some functionality to all buttons, I can do
const buttons = document.querySelectorAll(".btn");
buttons.forEach(btn=>{
btn.addEventListener("click",(e)=>{
//some code here
})
})
In react, how can I do the same thing, instead of adding "onClick" to every single button? Because imagine if there are 20 buttons like this:
<button className="btn" onClick={()=>{
//some code here
}}>button</button>
I could still use querySelector like the javascript way, but I heard that is a bad practice in react. So I wonder if there is any other way that can make the code cleaner.
React is perfect for this, because it allows you to reuse components! You could make a component that contains your click handler, then reuse it throughout your application.
const MyReusableButton = () => {
const myClickHandler = () => {
console.log("Clicked!");
}
return <button onClick = {myClickHandler}>Click Me</button>;
}
const App = () => {
// now I can reuse my button component as many times as I want!
return (
<div>
<MyReusableButton />
<MyReusableButton />
<MyReusableButton />
<MyReusableButton />
</div>
);
}
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>
Make a list that describes whatever is unique about your buttons. Map the list into your buttons.
const nums = [0,1,2,3,4,5]
return <div>
{nums.map(num =>
<button onClick={() => console.info("clicked" + num)}>
This is button {num}
</button>
)}
</div>
Instead of attaching a listener to each button you can use event delegation to attach one listener to a container to watch for events as they "bubble up" the DOM from each child element/component.
function Example() {
function handleClick(e) {
const { nodeName, textContent } = e.target;
if (nodeName === 'BUTTON') {
console.log(textContent);
}
}
return (
<div onClick={handleClick}>
<button>Click me 1</button>
<button>Click me 2</button>
<button>Click me 3</button>
<button>Click me 4</button>
</div>
);
};
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>