리액트에서 반복되는 로직을 효율적으로 재사용하는 방법을 생각해봅시다.
<Component render={(data) => <PropComponent data={data} />}
고차 컴포넌트는 컴포넌트 로직을 재사용하기 위한 React의 고급 기술입니다.
// 기본 코드
const 향상된_컴포넌트 = 고차_컴포넌트(래퍼_컴포넌트);
const ButtonComponent = ({ onAction, children }) => <button onClick={onAction}>{children}</button>
const Component = withTest(withLoader(withLog(ButtonComponent)));
보통 with prefix를 사용하여 만들어줍니다.
Context API 이전에는 HOC를 많이 사용했어요.
클로저를 활용하는 방식이예요. 아래의 withColor
함수를 살펴볼까요?
👆👆 withColor를 이용해 색을 가진 새로운 컴포넌트를 만들어내고 있네요.
❗ Redux도 사실은 HOC를 사용해서 만들어졌어요.
export default connect(mapState, mapDispatch)(login)
export default connect()(ToDoApp)
잠깐 redux에 관한 이야기 (HOC와는 다른 이야기예요)
설치: redux, react-redux
리덕스는 사실 js가 돌아가는 환경에서는 어디든 사용 가능해요.
react-redux는?
리액트와 리덕스를 바인딩해주는 역할을 하죠. 없으면 redux를 쓸 수가 없어요.
❗ Context API를 사용하면 깊어집니다.
<AAA.Provider>로 감싸주기 때문이죠.
Recoil, React Query, Emotion, React Router ...
등 라이브러리를 사용할수록 depth가 늘어나겠죠.
위의 라이브러리들도 결국은 Context API 사용하기 때문입니다.
너무 깊어지면 Context Hell이라고 해요.
😢 Context API 단점
🤔 그러면 리덕스는 왜 쓰지?
❓ Context API를 통한 전역 관리라.. 위험하지 않나요?
다들 전역 변수를 사용하지 말라고 하잖아요!
하지만 React에서의 전역 상태는 React에서 컨트롤하는 등의 캡슐화
가 되어있어요.
import { createContext } from 'react';
function App() {
const { ... } = useState(상태);
const {...} = useLoader(상태);
const [...] = useLog(상태);
return (
// some code
);
}
function helloA () {
console.log("Start");
AAA();
console.log("End");
}
function helloB () {
console.log("Start");
BBB();
console.log("End");
}
👆 Start와 End를 찍어주는 콘솔이 반복됩니다.
횡단 관심사란 핵심적인 기능이 아닌 중간 중간 삽입되어야할 기능들을 의미해요.
위의 코드에서는 AAA(), BBB()
가 되겠네요.