如何在 React 中将函数与钩子绑定?
Posted
技术标签:
【中文标题】如何在 React 中将函数与钩子绑定?【英文标题】:How can I bind function with hooks in 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
【参考方案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 正在询问如何解决功能组件的问题。以上是关于如何在 React 中将函数与钩子绑定?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 函数组件中不使用 useEffect 钩子获取数据?
如何在 React 中将输入值恢复为默认值 onClick?
如何使用/不使用 useEffect 钩子在 React JS 函数中获取更改的(新)状态值?