' React - ES6方式'绑定点击处理程序与参数

时间:2016-12-09 00:04:36

标签: javascript reactjs ecmascript-6

我已经阅读了大量有关() => {}语法的使用,构造函数中的绑定,道具等中的绑定等等的文章。但据我所知,绑定this代价高昂性能方面,并且使用箭头函数进行自动绑定非常昂贵,因为它每次都会创建一个新的匿名函数。

那么性能最佳,反应方式是什么?'处理这个问题?

构造函数中的绑定似乎适用于不需要传递参数的函数,如下所示:

constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
}

但是我们如何处理传递params的绑定函数,而不是在prop中绑定它,如下所示:

<li onClick={this.handleClick.bind(this, item.id)} />{item.name}</li>

在构造函数中绑定this然后在prop中绑定nullundefined会导致只绑定一次的绑定函数吗?

如果有任何误解,请随时纠正我。看起来这个问题的解决方案应该更为人所知并且更具普遍性......就好像我还没有生活在一块石头下一样!

修改

即使使用抽象,点击处理程序也不会与每个项呈现绑定?

在文章here中,他们将此示例提供给避免绑定点击处理程序,但是因为React.createClass会对方法进行自动绑定,所以我不知道这是怎么回事实际上并没有绑定每个项目渲染?

var List = React.createClass({
  render() {
    let { handleClick } = this.props;
    // handleClick still expects an id, but we don't need to worry
    // about that here. Just pass the function itself and ListItem
    // will call it with the id.
    return (
      <ul>
        {this.props.items.map(item =>
          <ListItem key={item.id} item={item} onItemClick={handleClick} />
        )}
      </ul>
    );
  }
});

var ListItem = React.createClass({
  render() {
    // Don't need a bind here, since it's just calling
    // our own click handler
    return (
      <li onClick={this.handleClick}>
        {this.props.item.name}
      </li>
    );
  },

  handleClick() {
    // Our click handler knows the item's id, so it
    // can just pass it along.
    this.props.onItemClick(this.props.item.id);
  }
});

有人可以解释一下吗? 这不就是它避免绑定每个ListItem渲染,但是由于在React.createClass中自动绑定,它仍然存在吗?

我使用class List extends Component语法而不是createClass尝试了此示例,并且this.handleClick未定义,因为handleClick方法未绑定到类。

在一天结束时,似乎这只是清理冗长,并且通过减少方法绑定实际上并没有提高性能...

5 个答案:

答案 0 :(得分:8)

适用于您的<li onClick={this.handleClick.bind(this, item.id)} />{item.name}</li>

这通常意味着你需要另一层抽象IE一个新的反应组件返回相同的元素,但你可以将onClick作为prop传递,并将item id传递给prop。然后在该组件中,您可以调用this.props.onClick(this.props.id)或者格式化数据。

本文阐述了绑定实例方法的每种方式之间的所有差异,以及每种方式如何影响性能https://medium.com/@housecor/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56#

答案 1 :(得分:5)

如果传递参数,则必须在render函数中绑定,而不是在构造函数中绑定。这可以使用bind或arrow函数来完成。

<li onClick={this.handleClick.bind(this, item.id)} />{item.name}</li>

<li onClick={() => this.handleClick(item.id)} />{item.name}</li>

答案 2 :(得分:0)

这有用吗? (使用TypeScript)

<Input type="password" onChange={this.onPasswordInputChange('primary')} />;
<Input type="password" onChange={this.onPasswordInputChange('secondary')} />;


interface IOnPasswordInputChange {
  (value: string): void;
}

private onPasswordInputChange = (type: string): IOnPasswordInputChange => {
  return (value: string) => {
    this.setState({ [type]: value });
  };
}

答案 3 :(得分:0)

onDelete(e) {
    const id = e.target.dataset.id;
}

<DropdownItem data-id={item.id} onClick={this.onDelete}><i className="fa fa-trash" /> Remove</DropdownItem>

答案 4 :(得分:0)

从语法上讲,我更喜欢使用箭头函数来进行绑定(特别是因为只有箭头函数才能将额外的参数传递给事件处理程序)。了解与箭头函数相关的性能损失后,我创建了一个实用程序函数,该函数接受箭头函数定义,这些定义将在组件的整个生命周期内进行缓存:

utils.js

export function createLambdaCache() {
  const result = {};
  return (key, lambda) => {
    if (!(key in result)) {
      result[key] = lambda;
    }
    return result[key];
  };
}

component.js

class MyComponent extends React.Component {
  render() {
    return (
      ...  
      // below 'btnEvent' string is used as a key to cache the event reference for subsequent renders
      <button onClick={this.bindWithArgs('btnEvent', evt => this.clickHander(id, evt))} />
      ...
    );
  }
  clickHandler(id, evt) {
    console.log(id, evt);
  }
  bindWithArgs = createLambdaCache();
}

createLambdaCache以上的

打字稿版本:

type evtHandler<E> = (evt: E) => void;
export function createLambdaCache<T = any>() {
  const result: {[key in keyof T]: evtHandler<any>} = {} as any;
  return <E>(key: keyof T, lambda: evtHandler<E>) => {
    if (!(key in result)) {
      result[key] = lambda;
    }
    return <evtHandler<E>>result[key];
  };
}