react.js - react 子组件回调父组件函数怎么传递参数啊?

查看:162
本文介绍了react.js - react 子组件回调父组件函数怎么传递参数啊?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

下面是一个简单的demo:
版本一:

import React from 'react';
class GroupItem extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      groupListData : props.groupListData,
      delGroup : props.delGroup,
      editGroup : props.editGroup
    };
    this.del = this.del.bind(this);
  }
  del(id){
    console.log(id);
    console.log('删除分组');
  }
  render(){
    return (
      <ul className="lcx02_newGroup-list">
        {this.state.groupListData.map((item) => {
          return (<li><span className="text-ellP">{item.name}</span><span onClick={this.del(item.id)} className="lcx02_delete fr" /><span className="lcx02_edit fr" /></li>)
        })}
      </ul>
    );
  }
}
GroupItem.propTypes = {
  groupListData : React.PropTypes.arrayOf(React.PropTypes.shape({})),
  delGroup : React.PropTypes.func
};
export default GroupItem;

版本二:

const GroupItem = ({groupListData, delGroup, editGroup}) => {
  return (
    <ul className="lcx02_newGroup-list">
      {groupListData.map((item) => {return (<li><span className="text-ellP">{item.name}</span><span onClick={delGroup(item.id)} className="lcx02_delete fr" /><span onClick={editGroup(item.id)} className="lcx02_edit fr" /></li>)})}
    </ul>
  );
};
GroupItem.propTypes = {
  groupListData : React.PropTypes.arrayOf(React.PropTypes.shape({})),
  delGroup : React.PropTypes.func,
  editGroup : React.PropTypes.func
};

li里面的点击删除事件如何传递呢?是不是思路错了?求大神指教一下。

解决方案

对事件的赋值的概念是"回调函数"的概念,不是"调用函数",是给于如onClick方法一个"函数"作为值,而不是给于一个函数调用,除非这个函数调用后会回传另一个函数。

什么是"函数调用",下面这个就是,除非有特别用意,这十之八九是错误的用法:

<ABC onClick={editGroup(item.id)} />

什么是赋于一个回调函数,下面这二个例子就是,这经常可见,通常会是正确用法:

<ABC onClick={editGroup} />

<ABC onClick={() => { editGroup(item.id) }} />

上面的第二种语法,它在React中会有执行期绑到里面的值的设计,类似于部份应用的概念,这是比较特别的。它可以用来当你在事件触发时有不同的传参时,要作一些其它的用途,例如像这里的要分辨是要删除哪个项目。

当你需要更多的传参时,也需要传入的事件对象时,就会写成像下面的语法:

<ABC onClick={(e) => { editGroup(item.id, e) }} />

而对应的触发事件时用的方法,应该也是同样的方法声明:

editGroup(id, e){
  // 这里写代码
}

或使用相似于箭头函数语法,可以省去在构造式里面作bind,如下:

editGroup = (id, e) => {
  // 这里写代码
}

以上为概略地对事件触发的赋给回调函数的说明。


那么,回头来看看题主的代码,这代码中有什么问题。

首先,在不论是版本一或版本二,对于onClick事件,都是赋给一个"函数的调用",所以不论是onClick={this.del(item.id)}onClick={delGroup(item.id)},必定不是那种鼠标点了后,触发事件然后作某些事情的结果。这与上面说的内容相违背。应该是要改为上面说的第二种,多个传参的语法,这就不多说了。

另一种方式在事件处理也很常见,有些特定的情况,可能没法在渲染的时候就能得到这种item.id值,或是它还不是个真正对应到真实DOM元素的事件方法(例如先赋到某个自订元件上)。这时候就要用别的技巧来作,实际上这与使用jQuery或纯JS来处理DOM元素上的事件类似的技巧,只是场景换到React上来而已。

一个简单的例子像下面这样,这是在点了li元素后,会删除掉自己li元素的例子:

AppTest.js

import React from 'react'
import Item from './Item'

class AppTest extends React.Component {
  constructor() {
    super()

    this.state = {
      items: ['aaa', 'bar', 'cat', 'foo'],
    }
  }

  handleItemClick = (e) => {
    const items = this.state.items.filter((item, index) => (
      index !== +e.target.getAttribute('data-id')
    ))

    this.setState({
      items,
    })
  }

  render() {
    return (
      <ul>
        {
          this.state.items.map((item, index) => (
             <Item
               text={item}
               key={index}
               index={index}
               onClick={this.handleItemClick}
             />
           ))
         }
      </ul>
    )
  }
}

export default AppTest

Item.js

import React from 'react'

const Item = (props) => (
    <li
      data-id={props.index}
      onClick={props.onClick}
      >
      {props.text}
    </li>
)

export default Item

关键是用了一个data-xxxli元素上,这个值代表数组中的索引值,然后在事件触发时,可以用下面的语法来获取这个值(加一元正号是为了强制转为数字而已),data-id随便取的,你要取data-index也可以,只要前面是data-就可以:

index !== +e.target.getAttribute('data-id')

也就是说这种方式,不需要在事件触发的回调函数,使用多个传参的语法。而是用data-xxx的对DOM元素的赋值,自行命名在真实DOM元素出现时的一些数据,这可以在某些情况下提供了一些便利。

data-*属性还可以用下面的其它两种方式获取到值:

e.target.attributes.getNamedItem('data-id').value
e.target.dataset.id

这篇关于react.js - react 子组件回调父组件函数怎么传递参数啊?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆