이번 포스팅에서는 고차 함수와 React 기술 중 하나인 고차 컴포넌트를 소개합니다.
고차 함수(HOF) 정의
고차 함수는 아래 두 가지 조건에서 한 가지 조건 또는 모든 조건을 만족하는 함수입니다.
- 함수를 반환하거나
- 함수를 인수로 하거나
자바스크립트에는 다양한 고차 함수를 지원하는데, 배열에서 사용 가능한 map, filter, sort, reduce 함수가 있습니다.
Array.prototype.map()
다음 코드는 배열 numArray을 map 함수를 사용하여 새로운 배열을 생성합니다.
var numArray = [100, 200, 300, 400];
var mapArray = numArray.map(num => num / 2);
console.log(mapArray);
// [50, 100, 150, 200]
map 함수는 함수를 인수로 취하므로 고차 함수입니다. 여기서 num => num / 2
는 화살표 함수(Arrow Function)로 작성된 함수입니다.
사용자 정의 고차 함수
이번에는 사용자가 직접 고차 함수를 정의합니다.
다음은 일반 함수입니다.
var myFunc1 = function(age) {
return age * 2;
}
var myFunc2 = function(age) {
return age / 2;
}
다음은 함수를 인수로 취하는 고차 함수입니다.
var hof = function(paramFunc, age) {
return paramFunc(age);
}
고차 함수 hof
에 첫 번째 매개변수로 myFunc1
함수를 전달하면, age * 2의 값을 반환합니다. myFunc2
함수를 전달하면, age / 2의 값을 반환합니다.
고차 컴포넌트(HOC)
React의 컴포넌트는 함수로 구현할 수 있으므로 "고차 컴포넌트(HOC)"로 불리는 고차 함수를 생성할 수 있습니다.
고차 컴포넌트는 컴포넌트를 인수로 취하고 새로운 컴포넌트를 반환하는 함수입니다.
예제
다음은 기능이 없는 컴포넌트입니다.
class RegularOneComponent extends React.Component {
render() {
return <p>첫 번째 컴포넌트</p>;
}
}
class RegularTwoComponent extends React.Component {
render() {
return <p>두 번째 컴포넌트</p>;
}
}
다음은 컴포넌트를 인수로 취하고 새로운 컴포넌트를 반환하는 고차 컴포넌트입니다.
function AuthWrapper(WrappedComponent) {
return class extends React.Component {
render() {
if (this.props.isLoggedIn) {
return <WrappedComponent {...this.props} />;
} else {
return <p>인증 실패</p>;
}
}
};
}
이 컴포넌트는 props.isLoggedIn
이 true이면, 전달받은 컴포넌트를 반환하고 그렇지 않으면 <p>인증 실패</p>
를 반환합니다.
다음은 일반 컴포넌트를 고차 컴포넌트에 전달하여 새로운 컴포넌트를 반환하는 코드입니다.
const WrappedOne = AuthWrapper(RegularOneComponent);
const WrappedTwo = AuthWrapper(RegularTwoComponent);
반환된 컴포넌트를 사용하는 코드입니다.
class App extends React.Component {
// ...
render() {
const { isLoggedIn } = this.state;
return (
<div>
<button onClick={this.toggleAuth}>
{isLoggedIn ? "Logout" : "Login"}
</button>
<WrappedOne isLoggedIn={isLoggedIn} />
<WrappedTwo isLoggedIn={isLoggedIn} />
</div>
);
}
}
지금까지 작성한 코드입니다.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
toggleAuth = () => {
this.setState((prevState, props) => ({
isLoggedIn: !prevState.isLoggedIn
}));
};
render() {
const { isLoggedIn } = this.state;
return (
<div>
<button onClick={this.toggleAuth}>
{isLoggedIn ? "Logout" : "Login"}
</button>
<WrappedOne isLoggedIn={isLoggedIn} />
<WrappedTwo isLoggedIn={isLoggedIn} />
</div>
);
}
}
function AuthWrapper(WrappedComponent) {
return class extends React.Component {
render() {
if (this.props.isLoggedIn) {
return <WrappedComponent {...this.props} />;
}
return <p>인증 실패</p>;
}
};
}
class RegularOneComponent extends React.Component {
render() {
return <p>첫 번째 컴포넌트</p>;
}
}
class RegularTwoComponent extends React.Component {
render() {
return <p>두 번째 컴포넌트</p>;
}
}
const WrappedOne = AuthWrapper(RegularOneComponent);
const WrappedTwo = AuthWrapper(RegularTwoComponent);
'React > React 문법' 카테고리의 다른 글
[React]Debounce 함수 구현 및 사용 (1) | 2021.11.15 |
---|---|
[React]객체 배열에서 값 변경 (1) | 2021.11.09 |
[React]div 외부 클릭을 감지 Hook으로 구현 (0) | 2021.11.02 |
[React]TypeScript기반 Type Alias vs interface (2) | 2021.10.22 |
[React]props.children에 props 전달 (0) | 2021.10.20 |
댓글