【问题标题】:onClick detection for both an li and button nested within lionClick 检测 li 和嵌套在 li 中的按钮
【发布时间】:2021-08-19 19:51:55
【问题描述】:

所以我试图在有一个删除按钮的同时实现直通功能。单击 li 文本将删除该项目,单击 del 按钮将其删除。

在功能上,它有效。问题是当我删除一个项目时,比如“2”,它会将直通样式应用于它下面的列表项。我猜这是因为“onClick”被检测到两次——在列表项和按钮内(因为按钮在技术上嵌套在列表项中)。当我按下 2 的 DEL 按钮时,会检测到列表项 3 的 onClick,应用 line-through 样式。纠正这个问题的最佳方法是什么?

我的带有 App 组件和 ListItem 组件的代码:


import React, { useState } from "react";
import ListItem from "./ListItem";
 
function App() {
  const [inputText, setInputText] = useState("");
  const [items, setItems] = useState([]);
 
  function handleChange(event) {
    const newValue = event.target.value;
    setInputText(newValue);
  }
 
  function addItem() {
    setItems((prevItems) => {
      return [...prevItems, inputText];
    });
    setInputText("");
  }
 
  function deleteItem(id) {
    setItems((prevItems) => {
      return prevItems.filter((item, index) => {
        return index !== id;
      });
    });
  }
 
  return (
    <div className="container">
      <div className="heading">
        <h1>To-Do List</h1>
      </div>
      <div className="form">
        <input onChange={handleChange} type="text" value={inputText} />
        <button onClick={addItem}>
          <span>Add</span>
        </button>
      </div>
      <div>
        <ul>
          {items.map((todoItem, index) => (
            <ListItem
              key={index}
              id={index}
              item={todoItem}
              delete={deleteItem}
            />
          ))}
        </ul>
      </div>
    </div>
  );
}
 
export default App;
 
____________________________________________________________________________________________________
 
import React, { useState } from "react";
 
function ListItem(props) {
  const [clickedOn, setClickedOn] = useState(false);
 
  function handleClick() {
    setClickedOn((prevValue) => {
      return !prevValue;
    });
  }
 
  return (
    <div>
      <li
        onClick={handleClick}
        style={{ textDecoration: clickedOn ? "line-through" : "none" }}
      >
        {props.item}
        <button
          onClick={() => {
            props.delete(props.id);
          }}
          style={{ float: "right" }}
        >
          <span>Del</span>
        </button>
      </li>
    </div>
  );
}
 
export default ListItem;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    正如您已经写过的,用户事件沿 DOM 树向上传播。要停止传播,您可以在事件处理程序中使用 event.stopPropagation() ref

            <button
              onClick={(event) => {
                event.stopPropagation();
                props.delete(props.id);
              }}
              style={{ float: "right" }}
            >
    

    【讨论】:

    • 好的,谢谢。我将其添加到我的代码中并解决了原始问题。现在,假设我有项目 1、2、3,然后单击 2 以应用直通。当我删除 2 时,第 3 项将取而代之,现在应用了直通。我是否还必须在 li onClick 处理程序中的某处添加 event.stopPropagation?
    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 2021-11-14
    • 2021-06-16
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多