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

How can I bind function with hooks in React?

基本上我们在构造函数中绑定事件处理函数,或者在 React class 组件中将它们作为箭头函数,如下所示

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>
  }
}

但是在 React v16.7.0 中引入 hooks 之后,class 组件变成了具有状态的功能组件。

那么如何在函数式组件中绑定函数和钩子呢?

没有必要在功能组件中绑定 functions/callbacks,因为函数中没有 this。在 类 中,绑定 this 很重要,因为我们要确保回调中的 this 引用组件的实例本身。但是,在构造函数中执行 .bind 有另一个有用的 属性 ,即在组件的整个生命周期中创建函数 once 并且没有创建新的回调render() 的每次调用。要使用 React hooks 只初始化一次回调,您可以使用 useCallback.

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>;
  }
}

挂钩

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

您不妨像这样编写上面的组件 Foo 并节省您自己的输入时间。注意 handleClick 周围的语法……它将闭包 handleClick 定义为 Foo 上的一个字段,而不是一个方法。这消除了您使用绑定覆盖构造函数中 OBject 的 'handleClick' 引用的需要。 (此外,如果您只是调用 'super',则无需定义构造函数!)

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

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

同样,对于您的原始示例,只需直接声明 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>
  }
}

人们来到 SO 并复制粘贴代码。将这个答案留在这里,这样 React 社区就不会错误地记住所有内容并可能做不必要的工作。

函数组件

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>;
}

提示:在使用 useCallback 时查看转译的代码,看看是否有必要,然后再将其放入。如果您不确定是否需要它,您可能不需要。并确定它对您有好处,请对其进行分析。