위 글은 50 React.js Super Hacks Every Developer Should Know를 번역 겸 약간의 각색을 곁들인 글로,
이 글은 5번째 중 4번째 글이다.
31. Custom Hooks for Fetching Data (데이터 가져오기 위한 커스텀 훅)
문제: 여러 컴포넌트에서 데이터 가져오기 로직을 재사용해야 합니다.
해결책: 데이터 가져오기 로직을 캡슐화하는 커스텀 훅을 만듭니다.
// PROBLEM: 데이터 가져오기 로직을 각 컴포넌트에서 중복하여 사용
const DataFetcher = ({ url }) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(url);
const result = await response.json();
setData(result);
setLoading(false);
};
fetchData();
}, [url]);
return loading ? <div>Loading…</div> : <div>{data.title}</div>;
};
// SOLUTION: 데이터 가져오기 로직을 커스텀 훅으로 캡슐화
import { useState, useEffect } from 'react';
const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(url);
const result = await response.json();
setData(result);
setLoading(false);
};
fetchData();
}, [url]);
return { data, loading };
};
// 사용 예시
const App = () => {
const { data, loading } = useFetch('https://api.example.com/data');
if (loading) return <div>Loading…</div>;
return <div>{data.title}</div>;
};
32. Optimizing Performance with React.memo (React.memo를 사용한 성능 최적화)
문제: 불필요한 리렌더링을 방지하여 컴포넌트 성능을 최적화해야 합니다.
해결책: React.memo
를 사용하여 함수형 컴포넌트를 메모이제이션하고, props가 변경될 때만 리렌더링합니다.
// PROBLEM: 불필요한 리렌더링 발생
const MyComponent = ({ value }) => {
console.log('Rendering MyComponent');
return <div>{value}</div>;
};
// SOLUTION: React.memo를 사용하여 불필요한 리렌더링 방지
const MyComponent = React.memo(({ value }) => {
console.log('Rendering MyComponent');
return <div>{value}</div>;
});
// 사용 예시
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<MyComponent value="Hello" />
</div>
);
};
33. CSS-in-JS with Styled Components (Styled Components를 사용한 CSS-in-JS)
문제: CSS를 별도로 관리하면 전역 네임스페이스 문제와 컴포넌트 캡슐화 부족이 발생할 수 있습니다.
해결책: Styled Components와 같은 CSS-in-JS 라이브러리를 사용하여 컴포넌트 내에서 스타일을 캡슐화합니다.
// PROBLEM: CSS 전역 네임스페이스 문제
/* styles.css */
.button {
background: palevioletred;
border-radius: 3px;
border: none;
color: white;
padding: 0.5em 1em;
}
// SOLUTION: Styled Components를 사용하여 스타일 캡슐화
import styled from 'styled-components';
const Button = styled.button`
background: palevioletred;
border-radius: 3px;
border: none;
color: white;
padding: 0.5em 1em;
`;
// 사용 예시
<Button>Styled Button</Button>
34. Using Prop-Types for Type Checking (Prop-Types를 사용한 타입 검사)
문제: 컴포넌트에 전달되는 props의 타입을 올바르게 확인하여 런타임 오류를 방지하고 싶습니다.
해결책: PropTypes
를 사용하여 컴포넌트의 props 타입을 검사합니다.
// PROBLEM: props 타입이 올바르지 않을 때 런타임 오류 발생
const MyComponent = ({ name, age }) => (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
// SOLUTION: PropTypes를 사용하여 타입 검사
import PropTypes from 'prop-types';
const MyComponent = ({ name, age }) => (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
MyComponent.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
};
// 사용 예시
<MyComponent name="John Doe" age={30} />
35. TypeScript for Type Safety (타입 안전성을 위한 TypeScript 사용)
문제: 개발 중에 오류를 잡기 위해 정적 타입 검사를 추가하고 싶습니다.
해결책: React와 TypeScript를 함께 사용하여 정적 타입 검사를 추가합니다.
// PROBLEM: JavaScript로 타입 검사가 어려움
const MyComponent = ({ name, age }) => (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
// SOLUTION: TypeScript를 사용하여 정적 타입 검사 추가
type Props = {
name: string;
age: number;
};
const MyComponent: React.FC<Props> = ({ name, age }) => (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
</div>
);
// 사용 예시
<MyComponent name="John Doe" age={30} />
36. Handling Side Effects with useEffect (useEffect를 사용한 부작용 처리)
문제: 컴포넌트 내에서 데이터 가져오기나 구독 설정 등의 부작용을 처리해야 합니다.
해결책: useEffect
훅을 사용하여 부작용을 처리합니다.
// PROBLEM: 부작용을 처리할 수 없음
const fetchData = async (url) => {
const response = await fetch(url);
const result = await response.json();
return result;
};
// SOLUTION: useEffect 훅을 사용하여 부작용 처리
const DataFetcher = ({ url }) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(url);
const result = await response.json();
setData(result);
setLoading(false);
};
fetchData();
}, [url]);
return loading ? <div>Loading…</div> : <div>{data.title}</div>;
};
// 사용 예시
<DataFetcher url="https://api.example.com/data" />
37. Context with Custom Hooks (커스텀 훅을 사용한 컨텍스트)
문제: 여러 컴포넌트에서 컨텍스트를 사용할 때 반복되는 코드를 줄이고 싶습니다.
해결책: 커스텀 훅을 만들어 컨텍스트 사용을 단순화합니다.
// PROBLEM: 컨텍스트 사용 코드가 반복됨
const ThemeContext = React.createContext('light');
const ThemedComponent = () => {
const theme = useContext(ThemeContext);
return <div className={`theme-${theme}`}>Themed Component</div>;
};
// SOLUTION: 커스텀 훅을 사용하여 컨텍스트 사용 단순화
const ThemeContext = React.createContext('light');
const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};
const ThemedComponent = () => {
const theme = useTheme();
return <div className={`theme-${theme}`}>Themed Component</div>;
};
// 사용 예시
const App = () => (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
38. Reducing Re-renders with React.memo (React.memo를 사용한 리렌더링 감소)
문제: 부모 컴포넌트가 리렌더링될 때 자식 컴포넌트가 불필요하게 리렌더링됩니다.
해결책: React.memo
를 사용하여 불필요한 리렌더링을 방지합니다.
// PROBLEM: 부모 컴포넌트 리렌더링 시 자식 컴포넌트가 불필요하게 리렌더링됨
const MyComponent = ({ value }) => {
console.log('Rendering MyComponent');
return <div>{value}</div>;
};
// SOLUTION: React.memo를 사용하여 불필요한 리렌더링 방지
const MyComponent = React.memo(({ value }) => {
console.log
('Rendering MyComponent');
return <div>{value}</div>;
});
// 사용 예시
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<MyComponent value="Hello" />
</div>
);
};
39. Error Handling in Async Functions (비동기 함수의 오류 처리)
문제: 비동기 함수 내에서 발생하는 오류를 처리해야 합니다.
해결책: useEffect
내에서 try-catch 블록을 사용하여 비동기 함수의 오류를 처리합니다.
// PROBLEM: 비동기 함수 내에서 발생하는 오류를 처리하지 않음
const fetchData = async (url) => {
const response = await fetch(url);
const result = await response.json();
return result;
};
// SOLUTION: try-catch 블록을 사용하여 비동기 함수의 오류 처리
const DataFetcher = ({ url }) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
if (loading) return <div>Loading…</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{data.title}</div>;
};
// 사용 예시
<DataFetcher url="https://api.example.com/data" />
40. Server-Side Rendering (SSR) with Next.js (Next.js를 사용한 서버 사이드 렌더링)
문제: SEO와 초기 로드 시간을 개선하기 위해 React 컴포넌트를 서버에서 렌더링하고 싶습니다.
해결책: Next.js를 사용하여 서버 사이드 렌더링을 구현합니다.
// PROBLEM: 클라이언트 사이드 렌더링만 사용하여 SEO와 초기 로드 시간이 좋지 않음
const Home = ({ data }) => {
return (
<div>
<h1>Server-Side Rendered Data</h1>
<p>{data.title}</p>
</div>
);
};
// SOLUTION: Next.js를 사용하여 서버 사이드 렌더링 구현
// pages/index.js
const Home = ({ data }) => {
return (
<div>
<h1>Server-Side Rendered Data</h1>
<p>{data.title}</p>
</div>
);
};
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return { props: { data } };
}
// 사용 예시
export default Home;
자주 사용하는 특징 (React 18 버전과 비교)
- Custom Hooks for Fetching Data (데이터 가져오기 위한 커스텀 훅):
- 데이터 가져오기 로직을 재사용할 수 있어 매우 유용합니다. 많은 프로젝트에서 공통적으로 사용됩니다.
- Optimizing Performance with React.memo (React.memo를 사용한 성능 최적화):
- 불필요한 리렌더링을 방지하여 성능을 최적화하는 데 많이 사용됩니다. React 18에서도 여전히 중요한 패턴입니다.
- CSS-in-JS with Styled Components (Styled Components를 사용한 CSS-in-JS):
- 스타일을 컴포넌트와 함께 캡슐화하여 사용하는 패턴은 여전히 인기가 많습니다. 여러 프로젝트에서 사용됩니다.
- Using Prop-Types for Type Checking (Prop-Types를 사용한 타입 검사):
- Prop-Types는 여전히 타입 검사를 위해 많이 사용되지만 TypeScript를 사용하는 프로젝트가 늘어나면서 그 비중이 줄어들고 있습니다.
- TypeScript for Type Safety (타입 안전성을 위한 TypeScript 사용):
- 타입 안전성을 보장하는 TypeScript는 많은 React 프로젝트에서 표준으로 사용되고 있습니다.
- Context with Custom Hooks (커스텀 훅을 사용한 컨텍스트):
- 컨텍스트를 사용하면서 코드의 중복을 줄이고 재사용성을 높이는 패턴으로 자주 사용됩니다.
- Error Handling in Async Functions (비동기 함수의 오류 처리):
- 비동기 작업 중 발생할 수 있는 오류를 처리하는 것은 중요하며, 많은 프로젝트에서 사용됩니다.
- Server-Side Rendering (SSR) with Next.js (Next.js를 사용한 서버 사이드 렌더링):
- SEO와 초기 로드 시간 최적화를 위해 서버 사이드 렌더링은 많은 프로젝트에서 필수적입니다.
잘 사용되지 않는 특징 (React 18 버전과 비교)
- Forwarding Refs (Refs 전달):
- 특정 상황에서만 필요합니다. 일반적인 컴포넌트에서는 덜 사용될 수 있습니다.
- Using Refs for Focus Management (Refs를 사용한 포커스 관리):
- 포커스 관리가 필요한 경우에만 사용되며, 자주 사용되지는 않습니다.
- Reducing Re-renders with React.memo (React.memo를 사용한 리렌더링 감소):
- 특정 상황에서만 유용합니다. 특히 최적화가 중요한 경우에만 사용됩니다.
- CSS-in-JS with Styled Components (Styled Components를 사용한 CSS-in-JS):
- 모든 프로젝트에서 사용되는 것은 아닙니다. 여전히 CSS 모듈이나 전통적인 CSS를 사용하는 프로젝트도 많습니다.
- Using Prop-Types for Type Checking (Prop-Types를 사용한 타입 검사):
- TypeScript 사용이 증가하면서 Prop-Types의 사용 빈도는 줄어들고 있습니다.
관련 글
2024.06.13 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (1)
[React] React 개발을 하며 지키면 좋을 것들 (1)
2024.06.15 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (3)2024.06.13 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (1)2024.06.09 - [Programming Language/Javascript] - [JS
juniortunar.tistory.com
2024.06.14 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (2)
[React] React 개발을 하며 지키면 좋을 것들 (2)
위 글은 50 React.js Super Hacks Every Developer Should Know를 번역 겸 약간의 각색을 곁들인 글로,팁이 50가지나 되는 만큼 한 글에 담기보단 10개씩 5번으로 나눠서 포스팅할 예정이다.이 글은 5번째
juniortunar.tistory.com
2024.06.15 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (3)
[React] React 개발을 하며 지키면 좋을 것들 (3)
위 글은 50 React.js Super Hacks Every Developer Should Know를 번역 겸 약간의 각색을 곁들인 글로,이 글은 5번째 중 3번째 글이다.21. Component Composition (컴포넌트 구성)문제: 복잡한 컴포넌트를 단순한 컴포넌
juniortunar.tistory.com
2024.06.17 - [Programming Language/React] - [React] React 개발을 하며 지키면 좋을 것들 (5)
[React] React 개발을 하며 지키면 좋을 것들 (5)
위 글은 50 React.js Super Hacks Every Developer Should Know를 번역 겸 약간의 각색을 곁들인 글로,이 글은 5번째 중 5번째(마지막) 글이다.41. Static Site Generation (SSG) with Next.js (Next.js를 사용한 정적 사이트 생
juniortunar.tistory.com