처음 만난 리덕스 (Redux) 문서


15.2 useDispatch()

다음 Redux와 관련된 훅은 useDispatch() 훅입니다.

이름에서 이미 짐작하셨겠지만 useDispatch() 훅은 Redux Action을 Dispatch할 수 있게 해주는 훅입니다.

const dispatch = useDispatch();

useDispatch() 훅은 이 코드처럼 별도의 파라미터 없이 그냥 호출해서 사용하면 되는데, 이렇게 호출하면 Redux Store의 dispatch 함수에 대한 reference를 리턴해줍니다.
그리고 이 dispatch함수에 Action 객체를 넣어서 호출하게 되면 해당 Action이 Dispatch 됩니다.

import { useDispatch } from 'react-redux';

function Counter(props) {
    const dispatch = useDispatch();

    return (
        <div>
            <button
                onClick={() => {
                    dispatch({ type: 'INCREASE_COUNT' });
                }}>
                카운트 증가
            </button>
            <button
                onClick={() => {
                    dispatch({ type: 'DECREASE_COUNT' });
                }}>
                카운트 감소
            </button>
        </div>
    );
}

export default Counter;

위 코드는 useDispatch() 훅을 사용한 예시 코드입니다.

이렇게 useDispatch() 훅을 사용해서 Redux Store의 dispatch 함수에 대한 reference를 가져오고, 이걸 사용해서 원하는 Action을 Dispatch할 수 있습니다.

여기에서는 Action 객체를 직접 만들어서 넣어주었는데, Action Creator를 만들고 이를 import해서 사용할 수도 있습니다.

import { useSelector, useDispatch } from 'react-redux';

function Counter(props) {
    const count = useSelector((state) => state.count);
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch({ type: 'INIT_COUNT', value: 0 });

        // 의존성 배열(dependencies array)에 넣어주는 것이 안전함
    }, [dispatch]);

    return <div>{count}</div>;
}

export default Counter;

그리고 위 코드처럼 dispatch 함수를 useEffect() 훅 내에서 사용하게되면, useEffect() 훅의 의존성 배열에 dispatch 함수를 넣어주는 것이 안전합니다.

앞에서 dispatch 함수는 Redux Store의 dispatch 함수에 대한 reference라고 설명했는데, 그래서 Redux Store의 인스턴스가 변경되지 않는 이상 dispatch 함수의 reference도 변하지 않습니다.
그리고 일반적으로 애플리케이션에서 Redux Store의 인스턴스가 변경되는 일은 없습니다.
다시 말해서, dispatch 함수가 가리키고 있는 reference도 바뀔 일이 없다는 것이죠.

하지만 이렇게 의존성 배열에 넣어주는 것이 안전한 이유는, 만약 의존성 배열에서 생략하면 ESLint 같은 Lint 툴에서 warning 메시지를 띄우게 되기 때문입니다.
그래서 그냥 이렇게 의존성 배열에 넣어주는 것이 안전하고 깔끔한 방법이라고 이해하면 됩니다.

function mapDispatchToProps(dispatch) {
    return {
        increaseCount: () => {
            dispatch({ type: 'INCREASE_COUNT' });
        },
        decreaseCount: () => {
            dispatch({ type: 'DECREASE_COUNT' });
        },
    }
}

앞에서 useSelector() 훅은 mapStateToProps() 함수와 동일한 역할을 한다고 설명드렸습니다.

그와 비슷하게 useDispatch() 훅은 Container를 만들 때 사용했던, connect() 함수의 mapDispatchToProps() 함수의 역할을 대신합니다.

하지만 차이점이 있다면 mapDispatchToProps() 함수에서는 이 예시 코드처럼 Dispatch하길 원하는 Action에 대해서 각각 함수를 만들어줘야 했지만, useDispatch() 훅은 리액트 함수 컴포넌트 내에서 dispatch 함수를 원할 때마다 호출 할 수 있다는 점입니다.

그래서 useDispatch() 훅을 사용하면 별도로 각 Action을 Dispatch을 하기 위한 함수를 작성할 필요없이, 원하는 곳에서 아무때나 원하는 Action을 Dispatch할 수 있습니다.

조금 더 자유도가 높다고 볼 수 있는 것이죠.


마지막 업데이트: 2023년 07월 14일 00시 00분

이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.