Redux와 React는 독립적인 라이브러리이다.
이 두 라이브러리를 함께 사용하는 경우 공식 Redux UI 바인딩 라이브러리인 React Redux
를 사용하여 두 라이브러리를 바인딩해야 한다.
이 라이브러리들을 이해하기 위해, react-redux 라이브러리의 여러 훅 중 useSelector을 만들어봤다. (useStore, useDispatch도 만들었으나 비교적 온전하진 않다)
useStore 훅을 사용하면 컴포넌트 내부에서 리덕스 스토어 객체를 직접 사용할 수 있다. (useStore는 컴포넌트에서 스토어에 직접 접근해야 하는 희소한 상황에만 사용한다)
// useStore.js
import { useContext } from "react";
import { ReactReduxContext } from "react-redux";
const useStore = () => useContext(ReactReduxContext).store;
export default useStore;
useStore 훅은 직접 구현하진 못했고 라이브러리의 ReactReduxContext를 사용하였다.
useContext, ReactReduxContext, useContext(ReactReduxContext).store 등을 콘솔에 찍어본 결과는 다음 이미지와 같다.
// useDispatch.js
import useStore from "./useStore";
const useDispatch = () => useStore().dispatch;
export default useDispatch;
useSelecotr 훅을 사용하면 connect 함수를 사용하지 않고도 리덕스의 상태를 조회할 수 있다.
// useSelector.js
import { useStore } from "react-redux";
import { useState, useEffect } from "react";
const useSelector = selector => {
const store = useStore();
const [state, setState] = useState(selector(store.getState()));
useEffect(() => {
const callback = () => {
const newState = selector(store.getState());
setState(newState);
};
store.subscribe(callback);
});
return state;
};
export default useSelector;
결국 react-redux는 react의 useContext에 있는 store에서 dispatch와 getState, subscribe 등을 활용한 라이브러리임을 깨달았다.