反应如何一次将事件监听器添加到多个元素
react how to add event listeners to multiple elements at once
为了证明我的问题,我将比较 vanilla javascript 并做出反应。在javascript,当我有
<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>
而且我想为所有按钮添加一些功能,我可以做到
const buttons = document.querySelectorAll(".btn");
buttons.forEach(btn=>{
btn.addEventListener("click",(e)=>{
//some code here
})
})
在 React 中,我怎样才能做同样的事情,而不是将“onClick”添加到每个按钮?因为想象一下如果有 20 个这样的按钮:
<button className="btn" onClick={()=>{
//some code here
}}>button</button>
我仍然可以像 javascript 那样使用 querySelector,但我听说这在 React 中是一种不好的做法。所以我想知道有没有其他方法可以让代码更干净。
制作一个列表,描述您的按钮的独特之处。将列表映射到您的按钮中。
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>
React 非常适合这一点,因为它允许您重用组件!您可以制作一个包含点击处理程序的组件,然后在整个应用程序中重复使用它。
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>
使用循环创建 JSX 对象数组并渲染它们。这是我之前从事的一个项目的示例。
let grid = []
maze.forEach((row, i) => {
let renderedRow = []
row.forEach((block, j) => {
renderedRow.push(<Block key={size.width * i + j}
inheritedType={block}
dimensions={defaultDimensions * scale}
onAction={() => {
setBlock(i, j)
setMazeFuture([])
}}
onDoubleClick={() => updateMaze(i, j, "empty")}
isDown = {isDown}
setIsDown={setIsDown}
appendToHistory={appendCurrentMazeToHistory}
/>)
})
grid.push(<Row key={i} columns={renderedRow} rowHeight={defaultDimensions * scale}/>)
})
return (
{grid}
)
您可以使用事件委托将一个侦听器附加到一个容器,而不是将侦听器附加到每个按钮,以在事件从每个子 element/component 中“冒出”DOM 时监视事件。
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>
为了证明我的问题,我将比较 vanilla javascript 并做出反应。在javascript,当我有
<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>
而且我想为所有按钮添加一些功能,我可以做到
const buttons = document.querySelectorAll(".btn");
buttons.forEach(btn=>{
btn.addEventListener("click",(e)=>{
//some code here
})
})
在 React 中,我怎样才能做同样的事情,而不是将“onClick”添加到每个按钮?因为想象一下如果有 20 个这样的按钮:
<button className="btn" onClick={()=>{
//some code here
}}>button</button>
我仍然可以像 javascript 那样使用 querySelector,但我听说这在 React 中是一种不好的做法。所以我想知道有没有其他方法可以让代码更干净。
制作一个列表,描述您的按钮的独特之处。将列表映射到您的按钮中。
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>
React 非常适合这一点,因为它允许您重用组件!您可以制作一个包含点击处理程序的组件,然后在整个应用程序中重复使用它。
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>
使用循环创建 JSX 对象数组并渲染它们。这是我之前从事的一个项目的示例。
let grid = []
maze.forEach((row, i) => {
let renderedRow = []
row.forEach((block, j) => {
renderedRow.push(<Block key={size.width * i + j}
inheritedType={block}
dimensions={defaultDimensions * scale}
onAction={() => {
setBlock(i, j)
setMazeFuture([])
}}
onDoubleClick={() => updateMaze(i, j, "empty")}
isDown = {isDown}
setIsDown={setIsDown}
appendToHistory={appendCurrentMazeToHistory}
/>)
})
grid.push(<Row key={i} columns={renderedRow} rowHeight={defaultDimensions * scale}/>)
})
return (
{grid}
)
您可以使用事件委托将一个侦听器附加到一个容器,而不是将侦听器附加到每个按钮,以在事件从每个子 element/component 中“冒出”DOM 时监视事件。
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>