简体   繁体   English

如何在 React 中使用钩子绑定函数?

[英]How can I bind function with hooks in React?

Basically we bind event handler functions in constructor or make them as arrow functions in React class components like below基本上我们在构造函数中绑定事件处理函数,或者在 React 类组件中将它们作为箭头函数,如下所示

class Test extends Component{
  constructor(props){
    super(props);
    this.state = { count:0 };
    this.setCount = this.setCount.bind(this);
  }

  setCount() {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return <button onClick={this.setCount}>Increase</button>
  }
}

But after hooks are introduced in React v16.7.0 the class components became functional components with state.但是在 React v16.7.0 引入钩子之后,类组件变成了带有状态的功能组件。

So how can I bind the function with hooks in functional component?那么如何将函数与函数组件中的钩子绑定呢?

There's no need to bind functions/callbacks in functional components since there's no this in functions. 没有必要在函数组件中绑定函数/回调,因为在函数中没有this In classes, it was important to bind this because we want to ensure that the this in the callbacks referred to the component's instance itself. 在类,重要的是要结合this是因为我们要确保this中提到的组件实例本身的回调。 However, doing .bind in the constructor has another useful property of creating the functions once during the entire lifecycle of the component and a new callback wasn't created in every call of render() . 但是,在构造函数中执行.bind还有另一个有用的属性,即在组件的整个生命周期中创建一次函数,并且在每次调用render()都不会创建新的回调。 To do only initialize the callback once using React hooks, you would use useCallback . 要仅使用React挂钩初始化回调,您可以使用useCallback

Classes

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

  handleClick() {
    console.log('Click happened');
  }

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

Hooks

function Foo() {
  const memoizedHandleClick = useCallback(
    () => {
      console.log('Click happened');
    },
    [], // Tells React to memoize regardless of arguments.
  );
  return <Button onClick={memoizedHandleClick}>Click Me</Button>;
}

People come to SO and copy-paste code.人们来到 SO 并复制粘贴代码。 Leaving this answer here, so the React community doesn't go around incorrectly memoizing everything and potentially doing more work than necessary.将这个答案留在这里,这样 React 社区就不会错误地记住所有内容并可能做不必要的工作。

Function components功能组件

function Foo() {
  const handleClick = function(){
    // use function statements to avoid creating new instances on every render
    // when you use `bind` or arrow functions
    console.log('memoizing can lead to more work!')
  };
  return <Button onClick={handleClick}>Click Me</Button>;
}

Tip: look at what code is transpiled when using useCallback and see if it's necessary, before dropping it in. if you're not sure you need it, you probably don't.提示:在使用useCallback查看转译了哪些代码,看看是否有必要,然后再将其放入。如果您不确定是否需要它,您可能不需要。 and to be sure it's doing you good, profile it.并确定它对您有好处,请对其进行分析。

You might as well write the component Foo above like this and save yourself some typing. 您也可以像这样编写上面的组件Foo并节省一些打字。 Note the syntax around handleClick ... it defines the closure handleClick as a field on Foo, rather than as a method. 注意handleClick的语法...它将闭包handleClick定义为Foo上的一个字段,而不是一个方法。 This removes the need for you to use bind to overwrite the OBject's 'handleClick' reference in the constructor. 这使您不必使用bind来覆盖构造函数中的OBject的'handleClick'引用。 (Also, you don't need to define a constructor if you're just calling 'super'!) (另外,如果你只是调用'super',你不需要定义构造函数!)

class Foo extends Component {
  handleClick = () => {
    console.log('Click happened');
  }

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

Similarly, for your original example, just declare state and setCount directly and to simplify your code: 同样,对于您的原始示例,只需直接声明state和setCount并简化代码:

class Test extends Component{
  state = {count: 0}

  setCount = () => {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return <button onClick={this.setCount}>Increase</button>
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM