onClick 子 <li> 反应

心理学家

我想在列表上添加带有反应的子类别,但是当我单击子猫时,我有两个事件:第一个是子类别,第二个是父类别。

我怎么能只有子类别?

有我的实际代码:

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章