useCallback

이는 성능 향상을 위해 불필요한 렌더링을 방지하려는 경우 적합하다. 자식 컴포넌트에 콜백을 전달하는 두 가지 방법을 비교해 보자.

1. class + inline arrow function

class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <Button onClick={() => this.handleClick()}>Click Me</Button>;
  }
}

https://codesandbox.io/s/21yqlr2mny

로그를 보면 <Button> 컴포넌트가 PureComponent 임에도 불구하고

2. class + constructor

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

https://codesandbox.io/s/ko48v8y5pv

위의 두 예제를 hook으로 만들면 아래와 같다.

1. functional component + arrow function

function Foo() {
  const handleClick = () => {
    console.log('Click happened');
  }
  return <Button onClick={handleClick}>Click Me</Button>;
}

https://codesandbox.io/s/z2vl88961p

2. functional component + useCallback

function Foo() {
  const memoizedHandleClick = useCallback(
    () => console.log('Click happened'), [],
  );
  return <Button onClick={memoizedHandleClick}>Click Me</Button>;
}

https://codesandbox.io/s/o73175ywwq