javascript - 使用地图触发多个 onClick 事件侦听器的嵌套列表
问题描述
我正在从一个 json 文件生成一个嵌套列表。我将该 json 文件转换为一个数组树。在这里,我想使用该数组树创建一个下拉列表,其中 onSidebarComponent 根据该数组显示数据。我使用数组映射并将数据推送到数组中并显示它们。
但是,每当我单击第一个索引数据时,它都会触发一次单击事件。每当我单击叶子节点数据时,它都会触发 3 个单击事件。另一方面,我不知道如何处理动态显示和隐藏单个列表数据。我提供了我的代码和一些屏幕截图以便更好地理解。
这是代码:
import React, { Component } from 'react';
import './App.css';
import data from './data/categories.json'
import { list_to_tree, search_from_tree } from './data/supportFunc'
class App extends Component {
constructor(props) {
super(props);
this.state = {
search: "",
show1: false,
show2: false,
show3: false
}
}
//----------------------------------------------------------------------------------------
onChangeHandler(e) {
this.setState({
search: e.target.value
})
}
//----------------------------------------------------------------------------------------
onNavPressed1(e, i) {
e.preventDefault()
console.log("button pressed1")
console.log(i)
this.setState({
show1: i,
search: ""
})
}
//----------------------------------------------------------------------------------------
onNavPressed2(e, i) {
e.preventDefault()
console.log("button pressed2")
console.log(i)
this.setState({
show2: i,
})
}
//----------------------------------------------------------------------------------------
onNavPressed3(e, i) {
e.preventDefault()
console.log("button pressed3")
console.log(i)
this.setState({
show3: i
})
}
//----------------------------------------------------------------------------------------
sideBarComponent(listData) {
if (this.state.search !== "") {
var clsName = "navbar-nav padd"
}
else {
var clsName = "navbar-nav padd collapse"
}
let arr = []
listData.map((d, i) => {
let subarr = []
d.children.map((child, j) => {
let subChildArr = []
child.children.map((subChild, k) => {
subChildArr.push(<li onClick={(e) => this.onNavPressed3(e, "_" + k)} className="nav-item listItem" key={i + "_" + j + "_" + k}>
{subChild.Name} <span className="float-right"> {subChild.children.length !== 0 ? <i className="fas fa-angle-right"></i> : " "}</span>
</li>)
})
subarr.push(<li onClick={(e) => this.onNavPressed2(e, "_" + j)} className="nav-item listItem" key={i + "_" + j}>
{child.Name} <span className="float-right"> {child.children.length !== 0 ? <i className="fas fa-angle-right"></i> : " "}</span>
<ul className={clsName}>{subChildArr}</ul>
</li>)
})
arr.push(<li onClick={(e) => this.onNavPressed1(e, "_" + i)} className="nav-item listItem" key={i}>
{d.Name} <span className="float-right ">{d.children.length !== 0 ? <i className="fas fa-angle-right"></i> : " "}</span>
<ul className={clsName}>{subarr}</ul>
</li>)
})
return (<nav className="navbar">
<ul className="navbar-nav navbar-width">
{arr}
</ul>
</nav>
)
}
//----------------------------------------------------------------------------------------
render() {
var val = this.state.search.toUpperCase()
var listData = list_to_tree(data)
var newListData = search_from_tree(listData, val)
// console.log("listData======")
// console.log(newListData)
return (
<div className="App">
<header className="App-header">
<input type="text"
name="search"
className="App-search"
onChange={(e) => this.onChangeHandler(e)}
value={this.state.search}
placeholder="Enter Products Category"
/>
</header>
<div className="nav-container">
{this.sideBarComponent(newListData)}
</div>
</div>
);
}
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
解决方案
发生了什么?
该行为是由事件传播引起的。有两种类型的事件传播 - 事件冒泡和捕获。
事件冒泡——首先触发最内层元素的事件,然后将事件传播到外层元素,即inside -> out。
事件捕获- 首先触发最外层元素的事件,然后将事件传播到内部元素,即out -> inside。
解决方案:
根据您的用例,我们在这里讨论事件冒泡。因此,为了防止事件传播到父元素,您必须e.stopPropagation()
在嵌套项onClick
处理程序中停止事件的传播。
e.stopPropagation()
我想在你的onNavPressed
处理程序中调用它是非常好的。
然而,这是一个基本的例子,它更清楚地说明了如何在 React 中防止事件冒泡(学分):
class List extends React.Component {
handleClick = e => {
// do something
}
render() {
return (
<ul onClick={this.handleClick}>
<ListItem onClick={this.handleClick}>Item</li>
</ul>
)
}
}
class ListItem extends React.Component {
handleClick = e => {
e.stopPropagation();
this.props.onClick();
}
render() {
return (
<li onClick={this.handleClick}>
{this.props.children}
</li>
)
}
}
学分:
推荐阅读
- reactjs - 使用导入的函数时,流不会推断类型细化
- python - 将数据类型“object”转换为“Float”
- c# - 当动态代理实体类型用作目标对象时,Audit.net 似乎挂起
- mysql - HiveQL 按列值的子字符串分组并识别缺失的组
- python - 元字符和反斜杠在这里做什么?
- react-native - TypeError: undefined is not a function (near '...this.state.categories.map...')
- assembly - 如何从 main() 返回大于 8 位的数字?
- sql - 按模糊条件分组
- android - Android findPreference() 坏了
- snowflake-cloud-data-platform - Snowflake 中的流:捕获一行的所有更改,而不仅仅是当前的净更改?