728x90
Hooks는 리액트 v16.8에 새로 도입된 기능으로 함수형 컴포넌트에서 상태 관리를 할 수 있는 useState, 렌더링 직후 작업을 설정하는 useEffect 등의 기능을 제공하여 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해준다.
useState
useState는 가장 기본적인 Hook이며, 가변적인 상태를 지닐 수 있게 해준다.
import React, { useState } from 'react';
const Counter = () => {
// const [상태 값, 상태 설정 함수] = useState(초기값);
const [value, setValue] = useState(0);
return (
<div>
<p>
value : <b>{value}</b>
</p>
<button onClick={()=>setValue(value + 1)}> +1</button>
<button onClick={()=>setValue(value - 1)}> -1</button>
</div>
);
};
export default Counter;
useEffect
useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다. 클래스형 컴포넌트의 componentDidMount와 componentDidUpdate를 합친 형태로 보아도 무방하다.
import React, { useState, useEffect } from 'react';
const Counter = () => {
// const [상태 값, 상태 설정 함수] = useState(초기값);
const [name, setName] = useState('');
const [nickname, setNickname] = useState('');
// 렌더링 직후마다 실행
useEffect(() => {
console.log('렌더링 완료');
console.log({
name,
nickname,
});
});
// 마운트될 때만 실행
useEffect(() => {
console.log('렌더링 완료');
console.log({
name,
nickname,
});
}, []);
// 특정 값이 업데이트될 때만 실행
useEffect(() => {
console.log('렌더링 완료');
console.log({
name,
nickname,
});
}, [name]);
// 컴포넌트가 언마운트되기 전, 업데이트되기 직전에 실행하려면 뒷정리 함수 반환
useEffect(() => {
console.log('렌더링 완료');
console.log({
name,
nickname,
});
return () => {
console.log('cleanup');
console.log(name);
};
}, [name]);
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickname = e => {
setNickname(e.target.value);
};
return (
<>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickname} />
</div>
<div>
<div>
<b>name:</b> {name}
<b>nickname:</b> {nickname}
</div>
</div>
</>
);
};
useReducer
useReducer는 useState보다 더 다양한 컴포넌트 상황에 따라 다양한 상태를 다른 값으로 업데이트해 주고 싶을 때 사용하는 Hook이다.
리듀서는 현재 상태, 그리고 업데이트를 위해 필요한 정보를 담은 액션값을 전달받아 새로운 상태를 반환하는 함수이다. 리듀서 함수에서 새로운 상태를 만들 때는 반드시 불변성을 지켜 주어야 한다.
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 };
case 'DECREMENT':
return { value: state.value - 1 };
default:
// 아무것도 해당되지 않을 때 기존 상태 반환
return state;
}
}
const Counter = () => {
// const [현재 상태 값, 액션을 발생시키는 함수] = useReducer(리듀서 함수, 리듀서 초기값);
const [state, dispatch] = useReducer(reducer, { value: 0 });
return (
<div>
<p>
value : <b>{value}</b>
</p>
<button onClick={() => dispatch({ type: 'INCREMENT' }> +1</button>
<button onClick={() => dispatch({ type: 'DECREMENT' }> -1</button>
</div>
);
};
export default Counter;
useReducer를 사용했을 때의 가장 큰 장점은 컴포넌트 업데이트 로직을 컴포넌트 바깥으로 빼낼 수 있다는 것이다.
728x90
300x250