如何解决在render里绑定方法和使用箭头函数

我们为什么不要在render方法里绑定方法和使用箭头函数?具体原因可以看一下这篇文章

这样的代码是不是似曾相识:

render() {
  const { id } = this.props;
  return (
    <Picker
       ...
       onChange={this.onDateChange.bind(this)}
       toggleOpen={this.onOpen.bind(this)}
       onClose={() => {this.onClose(id)}}
       ...
    />
 );
}
这要做不好的原因分为以下几个方面:
  • 不论是bind还是箭头函数在render执行时都会返回一个新的方法作为Props,旧的方法会被GC
  • 假如我们的组件是继承了PureComponent,那么在组件内部shouldComponentUpdate对比前后Props时,一定是不同的,PureComponent将失去作用
  • 如果你使用了eslint,它可能会给你警告,对于要解决一切警告的强迫症患者来说会很不爽,当然你也可以通过eslint的配置允许这样的操作
这些都不会产生程序崩溃之类的大问题,但是如果想让你的程序更规范,可以尝试以下方法:
  1. 在你的构造函数中绑定方法
constructor(props) {
    super(props);
    this.onDateChange = this.onDateChange.bind(this);
    this.onOpen = this.onOpen.bind(this);
 }

<Picker
    ...
    onChange={this.onDateChange}
    toggleOpen={this.onOpen}
    onClose={() => {this.onClose(id)}}
    ...
/>

很简单对不对,下面还有更酷的写法

class Demo extends Component {

  onDateChange = () => {
    // todo
  }

  onOpen = () => {
    // your code
  }

  onClose = () => {
    const { id } = this.props;
    // todo close
  }

  render() {
    return (
      <Picker
         ...
         onChange={this.onDateChange}
         toggleOpen={this.onOpen}
         onClose={this.onClose}
         ...
      />
   );
  }
}

如果以上方法你知道,但是你还不得不使用bind和箭头函数,那么一定是遇到了传参的问题,可能是下面这样:

class Demo extends Component {

  constructor(props) {
    super(props);
    this.state = {
      data: [
        { id: 0, name: '夜刀神·十香' },
        { id: 1, name: '日代千鹤' }
      ]
    };
  }

  onClick(id) {
    const person = this.state.data.find((p) => id === p.id);
    // your code
  }

  onMouseEnter(id) {
    // your code
  }

  render() {
    return (
      <div>
          this.state.data.map((person) => {
            const { id, name } = person;
            return (
              <div
                onClick={()=>{this.onClick(id)}}
                onMouseEnter={this.onMouseEnter.bind(this, id)}
              >
                { name }
              </div>
            )
          })
      </div>
    );
  }
}

这样可以直接把person.id通过箭头函数传入onClick方法,同样也有不使用箭头函数的解决方案


onClick = (e) => {
  const id = e.target.dataset.id;
  const person = this.state.data.find((p) => id === p.id);
  // your code
}

onMouseEnter = (e)=> {
  const id = e.target.dataset.id;
  // todo
}

render() {
  return (
    <div>
      this.state.data.map((person) => {
         const { id, name } = person;
         return (
          <div
            data-id={id}
            onClick={this.onClick}
            onMouseEnter={this.onMouseEnter}
          >
            { name }
          </div>
        )
      })
    </div>
  );
}

使用data-xx传递参数就可以解决这个问题了。

如有问题欢迎斧正。

参考地址:

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md

https://medium.com/@machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本笔记基于React官方文档,当前React版本号为15.4.0。 1. 安装 1.1 尝试 开始之前可以先去co...
    Awey阅读 7,805评论 14 128
  • 以下内容是我在学习和研究React时,对React的特性、重点和注意事项的提取、精练和总结,可以做为React特性...
    科研者阅读 8,297评论 2 21
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 8,107评论 2 35
  • GUIDS 第一章 为什么使用React? React 一个提供了用户接口的JavaScript库。 诞生于Fac...
    jplyue阅读 3,595评论 1 11
  • 回家沉淀这几个月 学到了不少技能 做饭越来越好吃 心境越来越平静 学会了承担责任 变得不再任性 懂得了换位思考 还...
    安倾阅读 259评论 0 0