parameterized-event-handler
React Component의 이벤트 핸들러를 파라미터로 전달하는 것은 필수다. 이벤트에 대한 참조값이 필수인지에 따라 ES6로 이벤트 핸들러를 파라미터로 전달 할 수 있는 방법은 다양하다.
Using the bind function
이벤트 핸들러를 this로 바인딩하는 것을 정의할 수 있다.
만약 custom parameter를 전달할 필요가 있다면, bind 호출시 파라미터에 전달하면 된다. SyntheticEvent는 핸들러에 두번쨰 파라미터로 전달될 것이다.
위에서 JSX prop 값인 bind
호출 함수는 렌더링할 때마다 새로운 함수를 생성할 것이다. 이것은 성능에 좋지 않고, 그 결과 가비지 컬렉터가 필요 이상으로 호출될 것이다. 또한, 업데이트 여부를 결정하기 위해 prop의 참조값 equality 여부를 체크하는 component에 새로운 함수가 prop으로 전달되면, 불필요한 리렌더를 발생시킨다.
렌더링 할 때마다 새로운 함수를 생성하는 것을 피하기 위해 constructor에서 함수를 바인딩할 수 있다.
button의 onClick prop에서 이벤트 핸들러를 지정하는 동안, 함수를 바인딩 할 필요가 없다. 그러나 이 방식의 단점은 파라미터에 동적으로 값을 전달할 수 없는 것이다.
Using ES6 arrow function
bind
를 매번 호출하는 것은 귀찮다. bind
호출을 피하기 위해 this
를 자동으로 함수에 바인딩 해주는 ES6의 arrow function을 사용할 수 있다.
또한, arrow function을 이용할 경우 이벤트 핸들러에 추가 파라미터도 전달할 수 있다.
위 예제 둘 다의 문제는 컴포넌트가 렌더링 될 때마다 다른 콜백 인스턴스가 생성되는 것이다. bind
function과 동일한 문제다.
모든 렌더링 마다 새로운 콜백 인스턴스 생성을 피하기 위해, callback을 bind하기 위해 property initializer 문법을 사용할 수 있다.
property initializer을 통해 이벤트 핸들러에 파라미터를 전달하기 위해, 우리는 currying을 이용해야 한다
커링은 호출 될 때마다 새로운 인스턴스가 생성되는 점을 주목하자.
Conclusion
currying으로 arrow function을 사용하는 것은 유저가 정의한 파라미터를 받는 이벤트 핸들러를 정의하기 위한, 깔끔하고 가장 간결(가장 효율적이지는 않지만)한 방법이다.
해당 포스팅을 번역하면서 마지막에 알려준 커링과 arrow function으로 작성한 이벤트 핸들러도 컴포넌트가 re-rendering될 경우 새로운 함수를 생성하는건 마찬가지일거라는 생각이 들었다. 댓글을 보자.
댓글
반박댓글
curried arrow function 또한 렌더링 될 때마다 새로운 메서드를 생성할 것이다. 알려준 방식은 나쁘다고 말하는 것은 아니지만, 그 방법은 다른 옵션들보다 반드시 "더 낫다고" 할 수 없다. 개인적으로 나는 extra parameter가 필요할 때 inline callback을 선호한다.
필자
currying은 렌더링 될 때마다 새로운 함수를 생성하지 않을 것으로 생각한다. 하지만, 새로운 함수는 버튼이 클릭 될 때마다 생성된다. onClick handler가 호출 될 때만 새로운 함수가 생성될 것이다.
반박댓글
curry 예제는 렌더링 될 때 호출된다. 생성된 함수는 이벤트 핸들러로 할당될 것이다.
Summary
아래 링크는 댓글의 예제 코드에 함수 참조값을 비교하여 새로운 객체가 생성됐는지 비교하는 버튼을 추가한 예제다.
Last updated
Was this helpful?