如何在 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
时查看转译的代码,看看是否有必要,然后再将其放入。如果您不确定是否需要它,您可能不需要。并确定它对您有好处,请对其进行分析。
基本上我们在构造函数中绑定事件处理函数,或者在 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
时查看转译的代码,看看是否有必要,然后再将其放入。如果您不确定是否需要它,您可能不需要。并确定它对您有好处,请对其进行分析。