컴포넌트의 크게 세 가지 주요 단계로 나눌 수 있다
Hook
을 사용하여 컴포넌트 생명주기에 간섭할 수 있다componentDidMount()
, componentDidUpdate()
, componentWillUnmount()
) 들을 함수형 컴포넌트에서는 Effect를 이용하여 비슷하게 구현할 수 있다useEffect(setup, dependencies?)
setup
: 컴포넌트가 DOM에 추가된 후, 실행할 함수cleanup function
을 반환할 수 있다cleanup function
는 먼저 실행한 후, setup
함수를 실행한다cleanup function
를 통해 이벤트 리스너나 타이머를 해제함으로써, 메모리 누수를 방지할 수 있다dependencies
(선택사항): 코드 내부에서 참조되는 모든 reactive values
의 배열reactive values
는 props
, state
및 컴포넌트 본체 내부에 직접 선언된 모든 변수와 함수를 포함한다[dep1, dep2, dep3]
와 같은 배열 형식으로 작성한다Object.is
를 사용하여 이전 값과 비교하는데, 생략하면 컴포넌트를 다시 렌더링할 때마다 Effect가 다시 실행된다useEffect(() => {
...
},[]); // dependencies 배열이 비어 있으므로, 컴포넌트가 마운트될 때만 실행된다
useEffect(() => {
...
},[count]); // count 값이 변경될 때마다 Effect가 실행된다
useEffect(() => {
let timer: NodeJS.Timeout;
const fetchData = async () => {
timer = setTimeout(() => {
setDiscount(false);
}, 3000);
};
fetchData();
return () => {
clearTimeout(timer); // useEffect 코드 실행 전에 항상 실행된다
};
}, [discount]);
서버로부터 더 많은 데이터를 가져오는 방법이다
XMLHttpRequest
문법 사용fetch()
문법 사용json()
메소드를 이용하여, JSON 문자열 형태의 응답 데이터를 JavaScript 객체로 변환할 수 있다axios
사용 axios
사용 방법import axios from 'axios';
axios.get('https://sample.com/data')
.then(({data}) => console.log(data) // 응답 데이터를 자동으로 JSON 객체로 변환
.catch(error => console.error('Error:', error));
const [tab, setTab] = useTab<number>(0); // 초기값 0 설정, 경우의 수 3가지이므로 0, 1, 2로 설정
<Nav variant="tabs" defaultActiveKey="link0">
<Nav.Item>
<Nav.Link onClick={() => setTab(0)} eventKey="link0">
제품영양정보
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link onClick={() => setTab(1)} eventKey="link1">
리뷰
</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link onClick={() => setTab(2)} eventKey="link2">
교환
</Nav.Link>
</Nav.Item>
</Nav>
interface TabContentProps {
tab: number;
}
const TabContent: FC<TabContentProps> = ({tab}) => {
return [
<div>제품 영양 정보입니다</div>,
<div>리뷰 관련 정보입니다</div>,
<div>교환/반품 관련 정보입니다</div>,
][tab]; // tab의 변수값에 따라 보여주는 값 다르게 설정
}
props
를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다
state
를 공유하기 어렵다는 것이다props
를 이요하여 부모 컴포넌트에서 자식 컴포넌트로 state
를 전달한다state
를 공유하는 것이 번거롭고 불편하다Context API
나 Redux
를 이용하여 컴포넌트 트리 전체에 데이터를 제공할 수 있다stock
상태 변수를 사용하기 위한 하위 컴포넌트를 contextStorage.Provider
로 감싸준다contextStorage.Provider
에 하위 컴포넌트에 전달할 값을 설정해준다// App.tsx
interface ContextValue {
stock: number[];
coffee: Coffee[];
}
export let contextStorage = createContext<ContextValue | undefined>(undefined); // 다른 곳에서 사용할 수 있도록 export 해준다
function App() {
const [stock] = useState<number[]>([10, 11, 12]);
...
return (
...
<Route
path="/detail/:id"
element={
<contextStorage.Provider value={{ stock, coffee }}>
<Detail coffee={coffee}></Detail> // stock 상태 변수를 사용하기 위한 하위 컴포넌트를 contextStorage.Provider로 감싸준다
</contextStorage.Provider>
}>
</Route>
)
}
// Detail.tsx
import {useContext} from 'react'
const Detail: FC<DetailProps> = ({ coffee }) => {
...
const ctx = useContext(contextStorage);
console.log(stx.stock); // [10, 11, 12]
}
props drilling
문제를 해결할 수 있다. props
전달로 인한 컴포넌트 간 의존성을 줄일 수 있다Context API
를 재사용할 때마다 매번 import
해줘야한다