[리액트] 커링 Currying
커링은 쉽게 말하자면 함수를 반환하는 함수
커링을 사용해야 하는 이유는 함수의 재활용 때문
function multiply(a, b) {
return a * b;
}
function multiplyTwo(a) {
return multiply(a, 2); // 함수 재활용
}
이를 응용해 n배 함수를 생성해주는 커링 함수를 만들 수 있다.
function multiplyX(x) {
return function(a) {
return multiply(a, x);
}
}
화살표 함수로 표현하면,
const multiplyX = x => a => multiply(a, x);
커링 함수의 사용
const multiplyThree = multiplyX(3);
const multiplyFour = multplyX(4);
const result1 = multiplyThree(3); // 3 * 3 =9
const result2 = multiplyFour(3); // 4 * 3 = 12
중간의 함수 선언(const multiplyThree = multiplyX(3); const multiplyFour = multplyX(4);) 생략 가능
const result1 = multiplyThree(3)(3); // 3 * 3 =9
const result2 = multiplyFour(4)(3); // 4 * 3 = 12
커링 함수의 특징은 인자를 따로 나누어 받아 실행할 수 있다.
multiply(a, b)의 방법은 함수를 실행할 때 인자를 한꺼번에 전달해야 하므로,
multiply(3)을 실행한 다음 다른 작업을 할 수 없다. 즉, 함수를 재활용하기 어렵다.
입력된 x에 a, b를 순서대로 곱한 다음 c를 더하는 ((x * a) * b) +c))라는 수학식을 커닝으로 구현해보기.
const equation= (a, b, c) => x =>((x * a) * b) + c; // a, b, c에 해당하는 값을 인자로 받아 함수를 반환.
const fomula = equation(2, 3, 4); 이와 같이 인자를 나중에 받아 실행할 함수를 행성해주는 함수가 '커링함수'
const x = 10;
const result = formula(x);
인자를 나중에 받아 실행할 함수를 행성해주는 함수가 '커링함수'
커링이란 함수의 인자를 다시 구성하여 필요한 함수를 만드는 패턴.
인자의 순서, 개수에 따라 비슷한 함수를 반복해서 작성해야 하는 부분은 커링을 이용하면 커링패턴으로 묶인 함수들을 쉽게 유지, 보수할 수 있으므로 유용하다.
상속패턴에서는 상속 구조에 따라 기능을 순서대로 물려받지만,
데코레이터 패턴에서는 필요한 기능만 탑재하여 각각 독립된 객체를 생성한다. 버튼과 기능을 분리.
이 것을 '독립된 데코레이터로 기능을 구성'했다고 한다.
자바 언어에는 이러한 테코레이터 패턴을 구현하기 위해 인터페이스를 사용하고,
자바스크립트 언어에서는 커링을 사용.
자바스크립트의 커링함수를 고차함수라고 하는데, 고차함수의 영어 표현을 살려 '하이어오더 컴포넌트'라고 칭함.
하이어오더 컴포넌트는 기존 컴포넌트에 기능을 덧입혀 새 컴포넌트로 반환하는 함수.
하이어오더가 반환하는 컴포넌트를 확장 컴포넌트라고도 부름. 확장 컴포넌트의 형태는 개발자가 직접 결정하면 됨.
보통은 생명주기 함수를 확장한 하이어오더 컴포넌트를 구성해야 하는 경우 클래스형 컴포넌트를 반환하도록 구현함.
하이어오더 컴포넌트가 두 가지 형태로 확장 컴포넌트를 반환하는 예
// 함수형 컴포넌트를 반환하는 하이어오더 컴포넌트 예
function higherOrderComponent(Component) {
return function Enhanced(props) {
return <Component {...props} />; //하이어오더 컴포넌트는 기존 컴포넌트를 확장한 컴포넌트이므로
기존 컴포넌트로 모든 프로퍼티를 모두 전달해 주어야 함.
}
}
// 클래스형 컴포넌트를 반환하는 하이어오더 컴포넌트 예
function higherOrderComponent(Component) {
return class Enhanced extends React.Component {
render() {
return <Component {...this.props} />;
}
}
}
하이어오더 컴포넌트와 확장 컴포넌트의 이름은 with로 시작