앞서 제작한 redux 세팅을 component에 적용하기 전에, 복습 및 숙지해야할 몇가지 중요한 개념이 있다.
redux의 state은 Immutable 하다
state를 변경할 때, react에서 하는 작업은 직접적으로 값을 '변경'하는 것이 아닌, 값을 '대체' 한다는 표현이 옳다. 이는 컴포넌트가 순수 함수 원칙을 유지할 수 있도록 도와준다. 다만, 외부 데이터를 가져와 사용하는 컴포넌트와 브라우저 이벤트에 의존하는 컴포넌트는 제외이다.
react의 state는 단방향 데이터 흐름의 특징을 갖고 있다.
이제 힘들게 만든 redux store을 react 컴포넌트에서 활용할 차례이다. react에서 사용하는 법은 다음의 2가지 주요 hook을 통해 할 수 있다.
useDispatch
action을 dispatch하는 데 사용된다. dispatch는 action의 state와 payload를 변경하는 유일한 방법이다.
const dispatch = useDispatch();
const onClick = () => {
dispatch(increment()); // increment() 는 숫자의 상태를 증가시키는 action이다.
};
useSelector
Redux 상태를 가져와 값을 사용한다. 다른 component에서 redux의 state가 필요할 때 사용한다. Redux 상태 스토어에서 원하는 데이터를 선택하여 컴포넌트에 주입한다. 예를 들어, 도서 구매 사이트에서 장바구니 페이지에 로그인한 user의 id와 이름 정보가 필요하다면 아래와 같이 사용할 수 있다.
const { userId, userName } = useSelector((state) => state.user);
숫자를 증가시키거나 감소시키는 counter 예제를 다음과 같이 간단하게 작성해 보았다.
import React from 'react';
import { useDispatch } from 'react-redux';
import { increment, decrement } from './actions';
const CounterComponent = () => {
const dispatch = useDispatch();
const counter = useSelector(state => state.counter);
return (
<div>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<br />
<p> current number : {counter} </p>
</div>
);
};
즉, react와 redux의 state관리를 정리하면 다음과 같다.
유저 이벤트 발생 -> dispatch action -> store가 이전 state와 최신 action을 조합하여 new state 도출 -> 컴포넌트가 update된 state를 인지 -> 결과에 맞게 re-render