여러개의 입력을 받는 함수를 한개의입력만 받는 여러개의 함수로 변환하는 것이다. 유연한 함수를 선언해 재사용성을 향상시킬 수 있지만, 성능이슈가 발생할 수 있다.
커링패턴은 함수영 프로그래밍에서 자주 사용되는 기법 중 하나인데 하스켈이나 스칼라 같은 함수형 프로그래밍 언어에는 기본적으로 내장되어 있다고 한다. 자바스크립트의 유연한 문법으로 이를 구현할 수 있다.
const applyDiscount = (할인율) => (가격) => 가격 - 가격 * 할인율
// 1. 변동성이 낮은 인자를 우선으로 받고, 높은 인자는 뒷순서로 받는 것이 좋다.
// 할인율이 0.1이라는 것을 기억하는 클로저
const tenPercentDiscount = applyDiscount(0.1)
// 두번째 인자를 나중에 전달하여 함수를 지연실행
const discountedPrice = tenPercentDiscount(1000)
console.log(discountedPrice)
// 2. 연속해서 호출 가능
const directlyDiscountedPrice = applyDiscount(0.1)(1000)
console.log(directlyDiscountedPrice)
더 이상 onClick={(e) => handleItemClick(itemId)}
와 같이 선언하지 않아도 된다.
function Component() {
const handleItemClick = itemId => (event) => {
console.log(itemId, event.target.value)
}
return (
<div>
{['item1', 'item2', 'item3'].map(itemId => (
<button key={itemId} onClick={handleItemClick(itemId)}>
Click {itemId}
</button>
))}
</div>
)
}
const createEndPoint = (base) => endpoint => params => {
const query = new URLSearchParams(params).toString();
return `${base}/${endpoint}?${query}`
}
// 기본 api url
const baseAPI = createEndPoint('https://example.com/api');
// 엔드포인트 확장
const fetchUser = baseAPI('users');
const fetchPost= baseAPI('posts');
const userAPIPath = fetchUser({id: 1, name: 'lee'});
// 커링 함수를 이용한 HOC 선언
function withLoading(WrappedComponent) {
return function({ isLoading, ...rest }) {
if (isLoading) {
return <div>Loading...</div>;
} else {
return <WrappedComponent {...rest} />;
}
};
}
// 예시 컴포넌트 선언
function MyComponent({ data }) {
return (
<div>
<h1>My Component</h1>
<p>{data}</p>
</div>
);
}
// 사용 예시
const MyComponentWithLoading = withLoading(MyComponent);
function App() {
// 데이터를 가져오는 상태 시뮬레이션
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
return (
<MyComponentWithLoading isLoading={loading} data={data} />
);
}
// 커링 함수를 사용한 컴포넌트 생성 함수
const createComponent = (Component) => (properties) => {
return <Component {...properties} />;
};
// 커링 함수 사용하여 특정 컴포넌트 생성 함수 만들기
const createButton = createComponent("button"); // HTML button 요소
const createLabel = createComponent("label"); // HTML label 요소
// 개별 컴포넌트 생성
const BlueButton = () =>
createButton({ style: { color: "blue" }, children: "Click me" });
const LargeLabel = () =>
createLabel({ style: { fontSize: "large" }, children: "Label text" });
// 사용 예시
function App() {
return (
<div>
<BlueButton />
<LargeLabel />
</div>
);
}