Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试官:React事件绑定的方式有哪些?区别? #187

Open
huihuiha opened this issue Jul 5, 2021 · 3 comments
Open

面试官:React事件绑定的方式有哪些?区别? #187

huihuiha opened this issue Jul 5, 2021 · 3 comments

Comments

@huihuiha
Copy link
Contributor

huihuiha commented Jul 5, 2021

一、是什么

react应用中,事件名都是用小驼峰格式进行书写,例如onclick要改写成onClick

最简单的事件绑定如下:

class ShowAlert extends React.Component {
  showAlert() {
    console.log("Hi");
  }

  render() {
    return <button onClick={this.showAlert}>show</button>;
  }
}

从上面可以看到,事件绑定的方法需要使用{}包住

上述的代码看似没有问题,但是当将处理函数输出代码换成console.log(this)的时候,点击按钮,则会发现控制台输出undefined

二、如何绑定

为了解决上面正确输出this的问题,常见的绑定方式有如下:

  • render方法中使用bind
  • render方法中使用箭头函数
  • constructor中bind
  • 定义阶段使用箭头函数绑定

render方法中使用bind

如果使用一个类组件,在其中给某个组件/元素一个onClick属性,它现在并会自定绑定其this到当前组件,解决这个问题的方法是在事件函数后使用.bind(this)this绑定到当前组件中

class App extends React.Component {
  handleClick() {
    console.log('this > ', this);
  }
  render() {
    return (
      <div onClick={this.handleClick.bind(this)}>test</div>
    )
  }
}

这种方式在组件每次render渲染的时候,都会重新进行bind的操作,影响性能

render方法中使用箭头函数

通过ES6的上下文来将this的指向绑定给当前组件,同样再每一次render的时候都会生成新的方法,影响性能

class App extends React.Component {
  handleClick() {
    console.log('this > ', this);
  }
  render() {
    return (
      <div onClick={e => this.handleClick(e)}>test</div>
    )
  }
}

constructor中bind

constructor中预先bind当前组件,可以避免在render操作中重复绑定

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('this > ', this);
  }
  render() {
    return (
      <div onClick={this.handleClick}>test</div>
    )
  }
}

定义阶段使用箭头函数绑定

跟上述方式三一样,能够避免在render操作中重复绑定,实现也非常的简单,如下:

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick = () => {
    console.log('this > ', this);
  }
  render() {
    return (
      <div onClick={this.handleClick}>test</div>
    )
  }
}

三、区别

上述四种方法的方式,区别主要如下:

  • 编写方面:方式一、方式二写法简单,方式三的编写过于冗杂
  • 性能方面:方式一和方式二在每次组件render的时候都会生成新的方法实例,性能问题欠缺。若该函数作为属性值传给子组件的时候,都会导致额外的渲染。而方式三、方式四只会生成一个方法实例

综合上述,方式四是最优的事件绑定方式

参考文献

@mushroommie
Copy link

时隔多年,终于搞懂了一些

@ZZZWTGitHub
Copy link

hook之后没人这么玩了,只能面试用用

@Mebius1916
Copy link

1. 内联函数绑定

这是最直接的绑定方式,通常在元素的 JSX 属性中内联定义一个函数。

function MyComponent() {
  return <button onClick={() => alert('Button clicked!')}>Click me</button>;
}

2. 类方法绑定

对于类组件,需要在类的构造函数中使用 bind 绑定事件处理器的上下文,或者使用类属性语法定义为箭头函数来自动绑定。

使用 bind 方法

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert('Button clicked!');
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

使用箭头函数

class MyComponent extends React.Component {
  handleClick = () => {
    alert('Button clicked!');
  }

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

3. 函数组件中的事件绑定

在函数组件中,可以直接通过钩子如 useStateuseEffect 结合函数进行事件绑定。

function MyComponent() {
  const handleClick = () => {
    alert('Button clicked!');
  };

  return <button onClick={handleClick}>Click me</button>;
}
  • 内联函数和钩子适合简单事件或快速开发。
  • 类方法绑定适合复杂逻辑和业务。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants