대표적으로 사용되는 것 위주로 보겠습니다.
const [state, dispatch] = useReducer(reducer, { count });
첫번째 인자로 함수가 들어가고, 두번째 인자로 initialize 값이 들어갑니다.
반환값의 두번째 item에는 보통 dispatch
라는 이름을 사용합니다.
reducer
: state 를 변경하는 로직이 담겨 있는 함수
const reducer = (state, action) => {
if(action.type === 'PLUS') {
return {
count: state.count + 1,
};
}
return newState;
}
dispatch
: action 객체를 넣어서 실행합니다.
action
: 객체이고 필수 프로퍼티로 type을 가집니다.
function click() {
dispatch({ type: 'PLUS' });
}
import React, { useReducer, useEffect } from 'react';
const reducer = (state, action) => {
if (action.type === 'PLUS') {
return {
count: state.count + 1,
};
}
return state;
};
const Example8 = ({ count }) => {
const [state, dispatch] = useReducer(reducer, { count });
useEffect(() => {
setTimeout(() => {
dispatch({ type: 'PLUS' });
}, 2000);
}, []);
function click() {
dispatch({ type: 'PLUS' });
}
return (
<div>
<p>You clicked {state.count} times</p>
<button onClick={click}>Click me</button>
</div>
);
};
export default Example8;
실제로 변하지 않더라도, 매번 실행되어 불필요한 연산을 하는 어떤 값에 대한 처리를 해줍니다.
useMemo(함수, 디펜던시)
//const 디펜던시 가 변경이 없으면 고정
function sum(persons) {
console.log('sum...');
return persons.map(person => person.age).reduce((l, r) => l + r, 0);
}
const Example9 = () => {
const [value, setValue] = useState('');
const [persons] = useState([{ name: 'Mark', age: 38 }, { name: 'Hanna', age: 27 }]);
function change(e) {
setValue(e.target.value);
}
const count = sum(persons);
return (
<div>
<input value={value} onChange={change} />
<p>{count}</p>
</div>
);
};
위 코드에서
sum
함수는 persons가 변했을 때만 계산해 주면되지만, input의 value 값이 바뀔때마다 컴포넌트가 재 실행될 것이고, 그 때마다 계속 sum
함수를 실행합니다. 이는 큰 낭비입니다.
그래서 persons
에 의존적으로 사용하겠다는 의미로 useMemo
를 사용합니다.
const count = useMemo(() => {
return sum(persons);
}, [persons]);
// useMemo(함수, 디펜던시)
useRef
, useCallback
, useMemo
들은 한가지 특징이 있습니다.
render 사이에 어떤 상태를 유지하는 기능
이라는 점입니다.
클래스 컴포넌트
에서는 이러한 걱정을 할 필요가 없었습니다.
왜냐하면 클래스 컴포넌트
의 render 메소드만 실행되기 때문에 클래스 안에 있는 다른 것들이 그대로 유지가 됩니다. 하지만 함수 컴포넌트
는 매번 return render를 위해 함수가 실행되면서 함수 안에 있는 모든 것들은 전부 새로 생성되는 경향이 있기 때문에, 랜더 사이에 굳이 새로 생성할 필요 없도록 도와주는 것이 useRef
, useCallback
, useMemo
입니다.
Hook들은 공통적인 로직을 따로 빼서 다른곳에서도 사용할 수 있게 도와주는 특성을 가지고 있기 때문에 많은 유용한 Hook들이 Library로 나와 있습니다.