17.1 작업 환경 설정

//redux, react-redux라이브러리 설치
yarn add redux react-redux

//.prettierrc
{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80
}

17.2 UI 준비하기

17.3 리덕스 관련 코드 작성하기

액션 타입, 액션 생성 함수, 리듀서 코드를 작성. 작성 방법은 아래 두 가지로 나뉨.

  • actions, constants, reducers로 각각 디렉터리를 구분해서 작성하는 방법
  • Ducks패턴 : 액션 타입, 액션 생성함수, 리듀서 함수를 기능별로 파일 하나에 몰아서 다 작성하는 방식

  1. 액션 타입 정의하기
  2. 액션 생성 함수 만들기
  3. 초기 상태 및 리듀서 함수 만들기
  4. 루트 리듀서 만들기

17.4 리액트 애플리케이션에 리덕스 적용하기

17.4.1 스토어 만들기

17.4.2 Provider 컴포넌트를 사용하여 프로젝트에 리덕스 적용하기

17.4.3 Redux DevTools의 설치 및 적용 

//크롬 확장 프로그램 설치(Redux DevTools)
1.
const store = createStore(rootReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

2. 
패키지를 설치하여 적용(코드 훨씬 깔끔해짐)
yarn add redux-devtools-extension

import {composeWithDevTools} from "redux-devtools-extension";
const store = createStore(rootReducer, composeWithDevTools());

//index.js
import rootReducer from "./modules";
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import {composeWithDevTools} from "redux-devtools-extension";

const store = createStore(rootReducer, composeWithDevTools());

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById('root')
);

17.5 컨테이너 컴포넌트 만들기

const makeContainer = connect(mapStateToProps, mapDispatchToProps);
makeContainer(타깃 컴포넌트);

//connect 함수사용
const mapStateToProps = state => ({
    number: state.data.number
});

const mapDispatchToProps = dispatch => ({
    increase: () => dispatch(increase()),
    decrease: () => dispatch(decrease())
});

export default connect(mapStateToProps, mapDispatchToProps)(Container);


//bindActionCreators함수 사용
export default connect(
    state => ({
        number: state.data.number
    }),
    dispatch => bindActionCreators(
        {
            increase,
            decrease,
        }, dispatch)
)(Container);


//mapDispatchToProps 파라미터에 액션 생성함수 객체 삽입 (connect 함수가 내부적으로 bindActionCreators 작업 대신 해줌)
export default connect(
    state => ({
        number: state.data.number
    }),
    {
        increase,
        decrease
    }
)(Container);

17.6 리덕스 더 편하게 사용하기

17.6.1 redux-actions

//라이브러리 설치
yarn add redux-actions


//createAction, handleActions를 사용해서 가독성 향상
import {createAction, handleActions} from "redux-actions";

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';

export const increase = createAction(INCREASE);
export const decrease = createAction(DECREASE);

const initialState = {
    number: 0
};

const counter = handleActions(
    {
        [INCREASE]: (state, action) => ({number: state.number + 1}),
        [DECREASE]: (state, action) => ({number: state.number - 1}),
    },
    initialState
)

export default counter;

17.6.2 immer

//spread, 배열 내장 함수 대신 immer를 사용한 불변성 유지 업데이트

//전
({...state, input: data}),

//후
produce(state, draft => {
	draft.input = data
}),

17.7 Hooks를 사용하여 컨테이너 컴포넌트 만들기

17.7.1 useSelector로 상태 조회하기

const result = useSelector(state => state.data.num);

17.7.2 useDispatch를 사용하여 액션 디스패치하기

const dispatch = useDispatch();
dispatch({type : 'TEST_ACTION'});
useDispatch를 사용할 때는 성능 최적화를 위해 useCallback을 함께 사용하는 것을 권장.

17.7.3 useStore를 사용하여 리덕스 스토어 사용하기

const store = useStore();
store.dispatch({type : 'TEST_ACTION'});
store.getState();

17.7.5 useActions 유틸 Hook을 만들어서 사용하기

17.7.6 connect 함수와의 주요 차이점

useSelector를 사용할 때는 성능 최적화를 위해 React.memo를 컨테이너 컴포넌트에 사용해 주어야 함.

+ Recent posts