본문 - https://javascript.plainenglish.io/5-react-design-patterns-you-should-know-629030e2e2c7
같은 코드를 반복적으로 작성하는 것에 지쳐 있으삼? 리액트 스킬을 다음 단계로 향상시키고 싶으심? HOCS, Render Props, Hooks, and Context API 들의 React Design Pattern 들을 이해함으로써, 당신의 코딩에 대한 스킬을 향상시켜 줄 것이다
1. Container 그리고 Presentational Components ✨
처음으로 우리가 살펴볼 패턴은 container 와 presentational 컴포넌트를 분리하는 작업이다. 이 패턴은 data management 와 UI rendering 분리에 대한 내용 이라 할 수 있다. Container 컴포넌트는 어플리케이션의 data, state를 관리하는 역할을 한다. 동시에 presentational 컴포넌트는 UI rendering을 하는 역할이다.
Container 컴포넌트 예시
- data, state management role
import { useState } from 'react';
function TodoContainer() {
const [todos, setTodos] = useState([]);
function handleAddTodo(todo) {
setTodos([...todos, todo]);
}
return (
<TodoPresentational
todos={todos}
onAddTodo={handleAddTodo}
/>
);
}
Presentational 컴포넌트 예시
- UI rendering role
// render될 prop만 전달 받음에 FOCUS
function TodoPresentational({ todos, onAddTodo }) {
return (
<>
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<button onClick={() => onAddTodo({ id: Date.now(), text: 'New Todo' })}>
Add Todo
</button>
</>
);
}
data management를 하는 컴포넌트와 UI rendering 하는 컴포넌트를 분리(module 화) 함으로써, 코드가 더욱 이해하기 쉬워지고 maintain 하기에도 좋다.
2. Higher-Order Components (HOCs)
Higher-Order Components (HOC)는 컴포넌트 로직을 재사용 할 수 있게끔 해주는 패턴이다.
HOC 예시
import { useState, useEffect } from 'react';
function withLoading(WrappedComponent) {
return function LoadingComponent({ isLoading, ...props }) {
const [loading, setLoading] = useState(isLoading);
useEffect(() => {
setLoading(isLoading);
}, [isLoading]);
if (loading) {
return <div>Loading...</div>;
}
return <WrappedComponent {...props} />;
};
}
HOC 적용 예시
아래와 같이 위 예시에서 보여준 HOC를 적용 함으로써, 다른 컴포넌트 에서 loading state를 만들어줄 수 있다.
const TodoListWithLoading = withLoading(TodoList);
function App() {
const [isLoading, setIsLoading] = useState(false);
return (
<>
<button onClick={() => setIsLoading(true)}>
Load Todos
</button>
<TodoListWithLoading isLoading={isLoading} />
</>
);
}
HOCs를 사용 함으로써, 중복코드 없이 쉽게 공통 컴포넌트(common functionality)를 다수의 컴포넌트에 추가 할 수 있다.
3. Render Props
Render props 패턴은 HOC와 비슷하다. 하지만, component를 wrap 하기 위해서 higher-order function을 사용하는 대신에, 이 패턴은 function을 전달하기 위해 prop을 사용한다.
Render Props 패턴 예시
function Toggle({ children }) {
const [isVisible, setIsVisible] = useState(false);
function handleClick() {
setIsVisible(!isVisible);
}
return children({
isVisible,
toggle: handleClick
});
}
function App() {
return (
<Toggle>
{({ isVisible, toggle }) => (
<>
<button onClick={toggle}>Toggle</button>
{isVisible && <p>This content is visible</p>}
</>
)}
</Toggle>
);
}
Render Props 패턴은 component logic을 공유하기 위해서 훨씬 flexible한 방법이라 할 수 있다.
4. Hooks
Hooks는 state 와 리액트에서 functional components에 존재하는 다른 리액트 기능들을 사용하기 위한 방법 (Custom hook) 중 하나이다.
Hooks는 16.8 버전부터 Class Component의 대체자?로 소개가 되었다.
useState hook의 예시
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increase
</button>
</>
);
}
Hooks make it easy to use state and other features in functional components and make it easier to write and understand the code.
5. Context API
The Context API는 Parent Component 에서 Child Component로 data를 전달 할 때, prop을 통해 전달 하지 않을 수 있도록 해준다. 즉, prop drilling(prop전달: parent -> child -> child -> child -> child)을 보안 해준다.
context 와 provider 생성 방법의 예시
import { createContext, useState } from 'react';
export const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
context 와 provider 사용 예시
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
function ThemeToggler() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<>
<p>Current theme: {theme}</p>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
</>
);
}
Using the Context API, we can easily share data across multiple components without passing props through multiple levels.
Personal Note
대체적으로 쉽게 이용 할 수 있는 내용이였으며, 유용한 부분은 Container and Presentational Components 에 대한 concept 같다. 나중에 현업에서 적용 할 수 있는 기회가 있다면 참고하여 구조를 설계해도 좋은 방법이라 생각 된다. (어쩌면 필수?)
'Translate Work' 카테고리의 다른 글
타입스크립트 컴파일러의 컴파일 과정 (0) | 2023.04.10 |
---|---|
리액트의 Referential Equality (0) | 2023.03.09 |