안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[리액트를 다루는 기술]의 책을 참고하여 포스팅한 개인 공부 내용입니다.
Hooks - useState, useEffect
useState
- 가장 기본적인 Hook
- 함수 컴포넌트에서도 가변적인 상태를 지닐 수 있게 해줌
- 상태 관리 시 사용
Counter.js
import { useState } from 'react';
const Counter = () => {
const [ value, setValue ] = useState(0);
return(
<div>
<p>현재 카운터 값은 <b>{value}</b>입니다.</p>
<button onClick={() => setValue(value + 1)}>+1</button>
<button onClick={() => setValue(value - 1)}>-1</button>
</div>
);
};
export default Counter;
useState 함수의 파라미터에 기본 값을 넣어주어 value의 기본 값은 0으로 설정 되어 있습니다.
함수 호출 시 배열을 반환하게 되는데, 배열의 첫 번째 원소는 상태 값 / 두 번째 원소는 상태를 설정하는 함수입니다.
해당 함수에 파라미터를 넣어 호출하면, 값이 전달 받은 파라미터로 변경되고 리렌더링 됩니다.
App.js
import './App.css';
import Counter from './Counter';
const App = () => {
return <Counter />
}
export default App;
카운터가 정상적으로 작동하는 것을 확인할 수 있습니다.
useState 여러 번 사용하기
하나의 useState는 하나의 상태 값만을 관리할 수 있으므로, 관리할 상태가 여러 개라면 useState를 여러 번 사용하면 됩니다.
Info.js
import { useState } from "react";
const Info = () => {
const [ name, setName ] = useState('');
const [ nickname, setNickname ] = useState('');
const onChangeName = (e) => {
setName(e.target.value);
}
const onChangeNickname = (e) => {
setNickname(e.target.value);
}
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
}
export default Info;
App.js
import './App.css';
import Info from './Info';
const App = () => {
return <Info />
}
export default App;
name과 nickname 총 2개의 상태를 2개의 useState로 관리할 수 있는 것을 확인할 수 있습니다.
useEffect
- 렌더링될 때마다 특정 작업을 수행하도록 설정
- 클래스형 컴포넌트의 componentDidMount와 componentDidUpdate를 합친 형태
Info.js
import { useState, useEffect } from "react";
const Info = () => {
const [ name, setName ] = useState('');
const [ nickname, setNickname ] = useState('');
useEffect(() => {
console.log('렌더링이 완료되었습니다!');
console.log({ name, nickname });
});
const onChangeName = (e) => {
setName(e.target.value);
}
const onChangeNickname = (e) => {
setNickname(e.target.value);
}
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
}
export default Info;
이처럼 렌더링이 완료된 후 작업이 수행된 것을 확인할 수 있습니다.
마운트될 때만 실행하고 싶을 때
useEffect 내 작업을 맨 처음 렌더링될 때만 실행하고 업데이트될 때는 실행하지 않고 싶다면,
두 번째 파라미터에 빈 배열을 넣어줍니다.
Info.js - useEffect
useEffect(() => {
console.log('마운트될 때만 실행!!');
}, []);
name과 nickname을 입력하여도 (업데이트로 리렌더링 되어도), 콘솔 창에는 '마운트될 때만 실행!!'이 한 번 찍히는 것을 확인할 수 있습니다.
특정 값이 업데이트될 때만 실행하고 싶을 때
name의 값만 업데이트가 되었을 때만 특정 작업을 수행하고 싶을 땐, 두 번째 파라미터의 배열 안에 검사하고 싶은 값을 넣어줍니다.
Info.js - useEffect
useEffect(() => {
console.log(name);
}, [name]);
nickname을 업데이트 하였을 땐 useEffect 내 특정 작업이 수행되지 않았음을 확인할 수 있습니다.
배열 안에는 useState로 관리하고 있는 상태 혹은 props로 전달 받은 값 등을 사용할 수 있습니다.
뒷정리하기
useEffect는 렌더링 된 후 특정 작업을 수행하지만,
언마운트 되기 전이나 업데이트되기 직전에 특정 작업을 수행하고 싶을 때는 useEffect에서 뒷정리(cleanup) 함수를 반환해 줍니다.
Info.js - useEffect
useEffect(() => {
console.log('effect - ', name);
// 뒷정리함수
return () => {
console.log('cleanup - ', name);
}
}, [name]);
App.js
import './App.css';
import { useState } from 'react';
import Info from './Info';
const App = () => {
const [visible, setVisible] = useState(false);
return (
<div>
<button onClick={() => setVisible(!visible)}>{visible ? '숨기기' : '보이기'}</button>
<hr/>
{visible && <Info />}
</div>
);
}
export default App;
렌더링될 때마다 뒷정리 함수가 나타나고, 업데이트되기 직전의 값을 보여주는 것을 확인할 수 있습니다.
(마찬가지로 언마운트될 때만 뒷정리 함수 호출을 원한다면, 두 번째 파라미터는 [ ]로 선언)
'JavaScript > React' 카테고리의 다른 글
React) Hooks - useCallback, useRef, 커스텀 Hooks 만들기 (0) | 2022.11.15 |
---|---|
React) Hooks - useReducer, useMemo (0) | 2022.11.15 |
React) 컴포넌트의 라이프사이클 메소드 (0) | 2022.11.14 |
React) 컴포넌트 반복 (map, filter, key) (0) | 2022.11.14 |
React) ref - 컴포넌트에 이름 달기 (0) | 2022.11.11 |