Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

So how can I bind the function with hooks in functional component?

like image 649
Hemadri Dasari Avatar asked Nov 08 '18 19:11

Hemadri Dasari


People also ask

How do you bind a function in React Hooks?

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() . To do only initialize the callback once using React hooks, you would use useCallback .

Can I use hook in function React?

Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don't work inside classes — they let you use React without classes. (We don't recommend rewriting your existing components overnight but you can start using Hooks in the new ones if you'd like.)

How do you pass function as props in React Hooks?

Define the function in the parent component. Pass it as a prop to the child component, e.g. <Child handleClick={handleClick} /> . Use the function in the child component.


2 Answers

There's no need to bind functions/callbacks in functional components since there's no this in functions. 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. 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(). To do only initialize the callback once using React hooks, you would use 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>;
}
like image 154
Yangshun Tay Avatar answered Oct 18 '22 01:10

Yangshun Tay


People come to SO and copy-paste code. Leaving this answer here, so the React community doesn't go around incorrectly memoizing everything and potentially doing more work than necessary.

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. and to be sure it's doing you good, profile it.

like image 42
brianyang Avatar answered Oct 18 '22 03:10

brianyang