【问题标题】:How can I bind function with hooks in React?如何在 React 中将函数与钩子绑定?
【发布时间】:2019-04-12 09:27:30
【问题描述】:

基本上我们在构造函数中绑定事件处理函数,或者在 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>
  }
}

但是在 React v16.7.0 中引入了钩子之后,类组件变成了有状态的函数式组件。

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

【问题讨论】:

  • 没有必要在函数组件中绑定函数,因为你没有使用this
  • 用箭头功能就不需要了
  • 好的,如果我使用带有 mapStateToProps 的 Redux 连接方法。如何访问 this.props 等功能组件中的 props 或仅访问 props?
  • 你只是使用道具...而不是this.props

标签: javascript reactjs react-native react-hooks


【解决方案1】:

没有必要在函数组件中绑定函数/回调,因为函数中没有this。在类中,绑定this 很重要,因为我们要确保回调中的this 引用组件的实例本身。但是,在构造函数中执行.bind 具有另一个有用的属性,即在组件的整个生命周期中创建函数一次,并且不会在每次调用render() 时创建新的回调。要使用 React 钩子只初始化一次回调,您可以使用 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>;
}

【讨论】:

  • 谢谢。我不能写像 const memoizedHandleClick = () => { console.log('点击发生'); 这样的事件处理函数吗? } ?
  • @Think-Twice 是的,你可以。但它会在每次渲染时重新创建处理程序(与在基于类的render() 中使用箭头函数相同)。
  • 好的,什么是useCallback?它是预定义的名称吗?
  • 是的,这是另一个钩子。你读过文档吗?您应该查看有关钩子的整个部分:reactjs.org/docs/hooks-intro.html
【解决方案2】:

人们来到 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 时转译了哪些代码,看看是否有必要,然后再将其放入。如果您不确定是否需要它,则可能不需要。为了确保它对你有好处,请对其进行分析。

【讨论】:

    【解决方案3】:

    您不妨像这样编写上面的组件Foo 并节省一些打字时间。注意 handleClick 周围的语法...它将闭包 handleClick 定义为 Foo 上的一个字段,而不是一个方法。这消除了您在构造函数中使用 bind 覆盖 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>
      }
    }
    

    【讨论】:

    • 这只是解决类组件绑定问题的另一种方法。 OP 正在询问如何解决功能组件的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 2020-08-08
    • 2020-02-16
    • 2021-09-29
    相关资源
    最近更新 更多