함수 컴포넌트로 state와 react 추가 기능들을 사용할 수 있다.
먼저 useState
를 import 해준다.
function App(){
const [count, setCount] = useState(0);
// "count"라는 새 상태 변수를 선언, 디폴트 값으로 0을 줌.
return(
<>
<p>{count}</p>
<button onClick={()=> setCount(count + 1)}>
Click me
</button>
< />
);
}
useState는 현재의 state값과 이 값을 업데이트하는 함수를 쌍으로 제공한다.
=> count
= 현재의 state값, setCount
= 값을 업데이트 하는 함수.
클래스 컴포넌트의 this.setState
와 차이점은 이전 state와 새로운 state를 합치지 않는다.
useState(0)
는 인자로 초기 state값을 하나 받는다. 위같은 경우는 0
.
Hook의 state는 객체일 필요가 없다! 물론 객체도 가능함.
function ExampleWithManyStates() {
// 상태 변수를 여러 개 선언했습니다!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
컴포넌트 안에서 데이터를 가져오거나 DOM을 직접 조작하는 작업할 때 쓰일 수 있다.
componentDidMount
나 componentDidUpdate
, componentWillUnmount
와 같은 목적이지만 useEffect
하나로 통합됨!
function App() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 비슷함.
useEffect(() => {
document.title = `You clicked ${count} times`;
}
return (
<div>
<p>You clicked {count} times</p>
<button onclick={() => setCount(count + 1)}
Click me!
</button>
);
}
useEffect
를 사용하면 DOM을 바꾼 뒤 effect 함수를 실행한다. 컴포넌트 내부에 선언됐기 때문에 props와 state에 접근할 수 있다.
const FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id,handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if(!isOnline){
return "Loading...";
}
return isOnline ? "Online":"Offline"
}
function FriendStatusWithCounter(props) {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
// ...
Hook을 사용하면 서로 관련있는 코드들을 한군데에 모아서 작성가능! 클래스 컴포넌트처럼 생명주기 메서드에 쪼개서 넣을 필요 없으니 편리함!
- 최상위에서만 호출해야 한다! 반복문, 조건문, 중첩된 함수 내에서 실행하면 안됨.
- 함수컴포넌트 내에서만 호출해야 한다. 일반 js에선 사용 노노! (커스텀 hook 내에서는 사용 가능)
custom hook을 사용하면 재사용하고 싶을 경우 언제든지 쓸 수 있다!
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
위 경우에 useFriendStatus
라는 custom hook을 만들어서 비슷한 상황에 사용가능하다.