反应如何一次向多个元素添加事件监听器

问题描述 投票:0回答:5

为了演示我的问题,我将比较普通的 javascript 和 React。在 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
   })
})

在反应中,我怎样才能做同样的事情,而不是向每个按钮添加“onClick”?因为想象一下如果有 20 个这样的按钮:

<button className="btn" onClick={()=>{
   //some code here
}}>button</button>

我仍然可以像 JavaScript 那样使用 querySelector,但我听说这在 React 中是一个不好的做法。所以我想知道是否有其他方法可以使代码更干净。

javascript reactjs onclick addeventlistener
5个回答
4
投票

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>


2
投票

您可以使用事件委托将一个侦听器附加到容器,以在事件从每个子元素/组件“冒泡”到 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>


1
投票

制作一个列表来描述按钮的独特之处。将列表映射到您的按钮中。

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>

0
投票

这种情况的最佳方法是事件委托,我们必须将事件侦听器附加到父元素并处理子元素上的事件。

function clickMe(e) {
const btn = e.target.closest(".btn");
if (!btn) return; 
// more code here
}
// the JSX code : 

<div className="test" onClick={clickMe}>
  <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>;

-2
投票

使用循环创建 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}
)
© www.soinside.com 2019 - 2024. All rights reserved.