클래스형 컴포넌트에서만 사용 가능한 state와 lifeCycle 기능을 함수형에도 사용할 수 있게 연동(hook into) 가능하게 하는 함수
⇒ hook은 class 안에서는 동작하지 않고, class 없이 react 사용이 가능하게 해줌.
재사용성
: 상태관련 로직을 추상화해 독립적으로 다룰 수 있고, 계층 변화 없이 재사용이 가능
간결성
: 메서드 기반이 아닌 로직 기반으로 나눌 수 있어서 컴포넌트를 함수 단위로 쪼갤 수 있음
→ 관련없는 로직이 섞여 들어가는 lifeCycle의 단점을 보완
: 현재 state 값과 state 값을 업데이트하는 함수를 반환
원형
const [state, setState] = useState(initialState);
→ state : current state
→ setState : function to update state
→ initialState : Initial value
사용하는 이유
상태 변화시 DOM(Document Object Model)을 다시 렌더링 해야하기 때문이다.
변화된 state가 화면에 보이려면 Update 상태에 들어가야 한다. 그러나, 객체의 메모리 주소를 이용해 state가 변경된 것을 판단하기 때문에, 내부 값만 변화한다. ⇒ 즉, 직접 state 값을 수정한다고 Update 상태로 들어가지 않는다!
따라서 useState를 사용하면, react 내부적으로 상태 변경을 감지해 컴포넌트의 재렌더링을 관리해준다.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>카운트: {count}</p>
<button onClick={increment}>증가</button>
</div>
);
}
export default Counter;
useState
훅을 사용하여 count
라는 상태 값을 선언하고, setCount
함수를 사용하여 상태 값을 업데이트한다. 버튼을 클릭할 때마다 count
상태값이 1씩 증가한다.: 리액트 컴포넌트가 렌더링 될 때 마다, 즉 DOM이 렌더링 된 이후에 작업을 실행할 수 있도록 명시함.
→ 컴포넌트 렌더링 - 화면 업데이트 - useEffect 실행
⇒ 생명주기의 메소드 기능을 수행.
원형
useEffect(콜백함수, 의존성배열)
1) 첫 번째 인자 : 콜백함수
컴포넌트가 마운트되거나 업데이트 될 때마다 실행되는 함수, 콜백 함수 내부에서 원하는 작업 수행 가능.
다른 함수가 실행을 끝낸 뒤 실행되는, callback되는 함수를 말한다.
2) 두 번째 인자 : 의존성 배열
배열에 포함된 값은 콜백 함수가 실행되는 조건을 지정, 즉 배열에 포함된 값들 중 하나라도 변경되면 콜백 함수 실행
useEffect(함수, )
⇒ 렌더링이 될 때마다 (마운트 후, 업데이트 후, 언마운트 전) 실행
useEffect(함수, [])
⇒ 최초 렌더링 시 실행(ComponentDidMount)
useEffect(함수, [state1, state2])
⇒ 최초 렌더링 + state의 변화가 있을 때 실행
(ComponentDidMount, getDerivedStateFromProps)
useEffect(() ⇒ {return ( () ⇒ 함수)})
⇒ 리턴하는 함수: clean-up, 컴포넌트가 언마운트 업데이트 되기 전에 실행
(ComponentWillUnmount)
→ API 호출을 통해 데이터를 가져오거나 state가 변경되는 point에 업데이트데이터를 가져오거나 업데이트 해야 할 때
→ 스크롤 이벤트, 리사이즈 이벤트 등 이벤트를 감지해 원하는 동작 수행 가능이벤트를 처리해야 할 때
→ 마운트된 타이밍이나 state가 변경된 업데이트 타이밍에 타이머를 시작하거나 인터벌을 실행할 수 있음타이머 및 인터벌 설정
import React, { useEffect, useState } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
return () => {
clearInterval(intervalId);
};
}, []);
return (
<div>
<p>경과 시간: {seconds}초</p>
</div>
);
}
export default Timer;
useEffect
훅을 사용하여 1초마다 seconds
상태값을 업데이트한다. useEffect
의 두 번째 인자로 빈 배열([]
)을 전달하여 컴포넌트가 처음 렌더링될 때 한 번만 실행되도록 설정하였다. useEffect
의 클린업 함수에서는 setInterval
을 해제하여 메모리 누수를 방지한다.context
: 일반적인 리액트에서 데이터는 props를 통해서 부모에서 자식에게 전달함.
어플리케이션 안의 여러 컴포넌트들에게 props를 전달해줘야 하는 경우 context 이용
const contextValue = useContext (ContextObject);
createContext(initialValue)
: 부모 컴포넌트에 작성, context 객체를 생성한다.
Provider: 생성한 context를 하위 컴포넌트에게 전달하는 역할을 한다.
Consumer: context의 변화를 감시하는 컴포넌트이다.
파라미터 initialValue는 Provider를 사용하지 않았을 때 적용될 초기값을 의미
Context.Provider
: 부모 컴포넌트에 작성, 생성한 context를 하위 컴포넌트에 전달
useContext(Context)
: 자식 컴포넌트에 작성, 설정한 상태를 불러올 때 사용
→ useContext를 사용하여 컨텍스트에 저장된 데이터를 다른 컴포넌트에서 가져와서 API 호출에 사용데이터 가져오기, API를 통해 데이터를 가져와야 하는 경우
→ useContext의 cleanup 함수를 사용하여 컴포넌트가 언마운트되기 전에 필요한 정리 작업을 수행 가능컴포넌트가 언마운트될 때 정리 작업을 해야 하는 경우
App.jsx
: App.jsx 파일은 앱 컴포넌트를 정의하고, UserContext.Provider를 사용하여 user 값을 제공하고, Profile 컴포넌트를 렌더링하는 역할.
import React from 'react';
import Profile from './Profile';
import { UserContext } from './UserContext';
function App() {
const user = {
name: '홍길동',
age: 25
};
return (
<UserContext.Provider value={user}>
<div>
<h1>앱</h1>
<Profile />
</div>
</UserContext.Provider>
);
}
export default App;
App
컴포넌트는 상위 컴포넌트로부터 받은 user
객체를 UserContext.Provider
를 통해 하위 컴포넌트에 전달한다.UserContext.Provider
컴포넌트는 UserContext
를 사용하여 전역적으로 데이터를 공유할 수 있는 Context를 제공한다. value
prop에 user
객체를 전달하여 하위 컴포넌트에서 사용할 수 있도록 한다.Profile
컴포넌트를 렌더링하고 있다.Profile.jsx
: Profile.jsx 파일은 프로필 컴포넌트를 정의하고, useContext를 사용하여 UserContext에서 user 값을 가져와 이름과 나이를 표시.
import React, { useContext } from 'react';
import { UserContext } from './UserContext';
function Profile() {
const user = useContext(UserContext);
return (
<div>
<h2>프로필</h2>
<p>이름: {user.name}</p>
<p>나이: {user.age}</p>
</div>
);
}
export default Profile;
Profile
컴포넌트는 UserContext
를 사용하여 user
객체를 가져온다. 이를 위해 useContext
훅을 사용하여 UserContext
의 값을 user
변수에 할당한다.user
객체의 속성들을 사용하여 프로필 정보를 렌더링한다.UserContext.jsx
: UserContext.jsx 파일은 UserContext를 생성하고, createContext를 사용하여 Context를 정의하는 역할.
import React from 'react';
export const UserContext = React.createContext();
UserContext
는 React.createContext()
를 사용하여 생성된 Context 객체다.UserContext
를 내보내는 UserContext.jsx
파일에서 export const UserContext = React.createContext();
코드를 사용하여 UserContext
를 내보낸다. 이렇게 내보낸 UserContext
는 다른 파일에서 사용할 수 있게 된다.⇒ 이처럼 코드를 나눠 작성하면 모듈성이 높아지고, 각 파일의 역할과 의존성이 분리되어 코드를 이해하고 유지보수하기 쉬워진다.