我想在列表上添加带有反应的子类别,但是当我单击子猫时,我有两个事件:第一个是子类别,第二个是父类别。
我怎么能只有子类别?
有我的实际代码:
getList(myList){
return myList.map((item) => {
let subList = '';
if (item.hasSub){
subList = (<ul>{this.getList(item.sub)}</ul>)
}
return (
<li onClick={() => {this.props.clicHandler(item.id)}}>{item.title}<div>{subList}</div></li>);
})
}
我正在使用递归方法来创建我的列表。我的实际数组是这样的:
this.list.push({id: 1, title:'coucou' , hasSub: false});
this.list.push({id: 2, title:'toto' , hasSub: false});
this.list.push({id: 3, title: 'cat', sub: [{id:4, title:'titi' , hasSub: false}, {id:5, title:'tutu' , hasSub: false}] , hasSub: true});
感谢您的帮助 !
问题是点击事件“冒泡”到父元素。解决方法是调用Event.prototype.stopPropagation
它。
在下面的代码片段中,我clickHandler
向组件添加了一个方法,并在其中getList
传递了事件 ( evt
) 和item.id
它。在该方法中,我evt.stopPropagation()
在调用this.props.clickHandler
. 但是,您也可以在父组件的clickHandler
方法中或在getList
. 选择最适合您的用例的任何内容。
class App extends React.Component {
constructor() {
super();
this.clickHandler = this.clickHandler.bind(this);
}
render() {
return <ul>{this.getList(this.props.items)}</ul>;
}
getList(list) {
return list.map((item) => {
const subList = item.hasSub && (<ul>{this.getList(item.sub)}</ul>);
return (
<li key={item.id} onClick={evt => {this.clickHandler(evt, item.id)}}>{item.title}<div>{subList}</div></li>
);
});
}
clickHandler(evt, itemId) {
// Stop event propagatation before calling handler passed in props
evt.stopPropagation();
this.props.clickHandler(itemId);
}
}
const data = [
{ id: 'a', title: 'A', hasSub: false },
{ id: 'b', title: 'B', hasSub: true, sub: [
{ id: 'b1', title: 'B1', hasSub: true, sub: [
{ id: 'b1a', title: 'B1a', hasSub: false },
] },
{ id: 'b2', title: 'B2', hasSub: false },
] },
{ id: 'c', title: 'C', hasSub: true, sub: [
{ id: 'c1', title: 'C1', hasSub: false },
{ id: 'c2', title: 'C2', hasSub: false },
] },
];
function clickHandler(itemId) {
console.log('clicked item', itemId);
}
ReactDOM.render(<App items={data} clickHandler={clickHandler}/>, document.querySelector('div'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div></div>
PS 你的代码很棒,但我可以推荐一种更多的“反应方式”来呈现嵌套项目吗?
您的组件的render
方法所做的是调用一个getItems
函数,该函数又递归地调用自身。然而,如果你记得大多数 React 组件本身可以被认为是函数,你可以重构你的代码,以便你的render
方法呈现一个递归呈现自身实例的<Items>
组件。
这种方法倾向于产生更小、更可重用且更易于测试的功能组件。看看下面的片段。
const Items = ({items, onClick}) => (
<ul>
{items.map(item => (
<li key={item.id} onClick={evt => onClick(evt, item.id)}>
{item.title}
{item.hasSub && <Items items={item.sub} onClick={onClick}/>}
</li>
))}
</ul>
);
const data = [
{ id: 'a', title: 'A', hasSub: false },
{ id: 'b', title: 'B', hasSub: true, sub: [
{ id: 'b1', title: 'B1', hasSub: true, sub: [
{ id: 'b1a', title: 'B1a', hasSub: false },
] },
] },
];
function clickHandler(evt, itemId) {
evt.stopPropagation();
console.log('clicked item', itemId);
}
ReactDOM.render(<Items items={data} onClick={clickHandler}/>, document.querySelector('div'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div></div>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句