티스토리 뷰

Javascript/React

React Redux

dev23 2024. 5. 14. 17:51
반응형

React Redux


- 리액트 애플리케이션에서 리덕스를 사용하면 상태 업데이트에 관한 로직을 모듈로 따로 분리하여 컴포넌트 파일과 별개로 관리할 수 있어 코드 유지 보수에 도움이 된다.
- 여러 컴포넌트에서 동일한 상태를 공유해야 할 때 매우 유용하며, 실제 업데이트가 필요한 컴포넌트만 리렌더링되도록 쉽게 최적화해 줄 수도 있다.

사용 라이브러리

- redux 및 react-redux 라이브러리를 설치한다.

컴포넌트 분리

- 리액트 프로젝트에서 리덕스를 사용할 때 가장 많이 사용하는 패턴은 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트를 분리하는 것이다.

 

프레젠테이셔널 컴포넌트

-  주로 상태 관리가 이루어지지 않고, 그저 props를 받아 와서 화면에 UI를 보여 주기만 하는 컴포넌트

 

컨테이너 컴포넌트

- 리덕스와 연동되어 있는 컴포넌트로, 리덕스로부터 상태를 받아 오기도 하고 리덕스 스토어에 액션을 디스패치하기도 함.

 


- 이러한 패턴은 리덕스 사용 시 필수 사항은 아니지만, 이 패턴을 사용하면 코드의 재사용성도 높아지고, 관심사의 분리가 이루어져 UI를 작성할 때 좀 더 집중할 수 있다.


파일 저장

- UI 관련 프레젠테이셔널 컴포넌트 : src/components
- 리덕스 연동 컨테이터 컴포넌트 : src/containers

리덕스 관련 코드

- 리덕스를 사용할 때는 액션 타입, 액션 생성 함수, 리듀서 코드를 작성해야 한다.
- 이 코드들은 각각 다른 파일에 작성하는 방법도 있고, 기능별로 묶어서 파일 하나에 작성하는 방법도 있다.


가장 일반적인 구조

- actions, constants(ActionTypes), reducers 라는 세 개의 디렉토리를 만들고 그 안에 기능별로 파일을 하나씩 만드는 방식이다. 
- 이 방식은 코드를 종류에 따라 다른 파일에 작성하여 정리할 수 있어 편리하지만, 새로운 액션을 만들 때마다 세 종류의 파일을 모두 수정해야 하기 때문에 불편하기도 하다.

Ducks 패턴

- 액션 타입, 액션 생성 함수, 리듀서 함수를 기능별로 파일 하나에 몰아서 모두 작성하는 방식이다.

모듈

- Ducks 패턴을 사용하여 액션 타입, 액션 생성 함수, 리듀서를 작성한 코드를 '모듈' 이라고 한다.
- 모듈 작성


1. 액션 타입 정의

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


 -> 액션 타입은 대문자로 정의하고, 문자열 내용은 '모듈 이름/액션 이름'과 같은 형태로 작성한다.
 

2. 액션 생성 함수 작성

export const increase = () => ({ type: INCREASE});
export const decrease = () => ({ type: DECREASE});


 -> 액션 타입 정의 후 액션 생성 함수를 만들어야 한다.
 -> 'export' 키워드를 붙여 이 함수를 다른 파일에서 불러올 수 있도록 한다.
 

3.초기 상태 및 리듀서 함수 작성

const intialState = {
	number: 0
};

function counter(state = intialState, action){
	switch(action.type){
		case INCREASE:
            return{
                number: state.number + 1
            };
		case DECREASE:
			return{
				number: state.number - 1
			};
        default:
        	return state;
    }
}

export default counter;


 -> 리듀서 함수에는 현재 상태를 참조하여 새로운 객체를 생성해서 반환하는 코드를 작성한다.
 

 

루트 리듀서 작성

- createStore 함수를 사용하여 스토어를 만들 때는 리듀서를 하나만 사용해야 한다.
- 때문에 만든 리듀서들을 합쳐 주어야 하는데, 이 작업은 리덕스에서 제공하는 combineReducers 라는 유틸 함수를 사용하면 된다.


리덕스 적용

- src/index.js 파일에 createStore 함수를 이용해 스토어를 생성하고 리듀서를 적용한다.

const store = createStore(rootReducer);


- 이후 Provider 컴포넌트로 App 컴포넌트를 감싸 준다.

<Provider store={store}>
	<App />
</Provider>

 


Redux DevTools 적용

- 패키지를 설치하지 않고 적용하기

const store = createStore(
    rootReducer, /* preloadedState */
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);


- 패키지를 설치하여 적용하기


1. 패키지 설치

$ yarn add redux-devtools-extension

 



2. 적용

import { composeWithDevTools } from 'redux-devtools-extension';

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

 

컨테이너 컴포넌트 작성

- 컴포넌트에서 리덕스 스토어에 접근하여 원하는 상태를 받아 오고, 액션도 디스패치하는 컴포넌트를 작성한다.

1. 프레젠테이셔널 컴포넌트를 불러온다.

2.  connect 함수를 사용하여 컴포넌트를 리덕스와 연동한다.

 

connect(mapStateToProps, mapDispatchToProps)(연동할 컴포넌트)

 

=>  mapStateToProps 

 - 리덕스 스토어 안의 상태를 컴포넌트의 props로 넘겨 주기 위해 설정하는 함수
 - state를 파라미터로 받아 오며, 이 값은 현재 스토어가 지니고 있는 상태를 가리킨다.


=> mapDispatchToProps

- 액션 생성 함수를 컴포넌트의 props로 넘겨 주기 위해 사용하는 함수
- store의 내장 함수 dispatch를 파라미터로 받아온다.


redux-actions 를 이용한 코드 간결화

- redux-actions를 사용하면 액션 생성 함수를 더 짧은 코드로 작성할 수 있다.
- 리듀서 작성 시에도 switch/case 문이 아닌 handleActions라는 함수를 사용하여 각 액션마다 업데이트 함수를 설정하는 형식으로 작성할 수 있다.
- redux actions 설치

$ yarn add redux-actions

 


createAction

- createAction 함수를 사용하여 액션 생성 함수를 만든다.

기존 : export const increase = () => ({type: INCREASE});
변경 : export const increase = createAction(INCREASE);

 

- createAction을 사용하면 매번 객체를 직접 만들어 줄 필요 없이 더욱 간결하게 액션 생성 함수를 선언할 수 있다.


handleActions

- handleActions 함수를 사용하여 리듀서 함수도 더 간단하고 가독성 높게 작성할 수 있다.

기존 :

function counter(state = initialState, action){
    switch(action.type){
        case INCREASE:
            return {
            	number: state.number + 1
        	};
        case DECREASE:
            return {
                number: state.number - 1
            };
    	default:
    		return state;
    }
}



변경 :

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



- handleAction 함수의 첫 번째 파라미터에는 각 액션에 대한 업데이트 함수를 넣어 주고, 두 번째 파라미터에는 초기 상태를 넣어 준다.

반응형

'Javascript > React' 카테고리의 다른 글

redux-saga  (0) 2024.05.14
redux-thunk  (0) 2024.05.14
React 생명 주기  (0) 2024.05.05
React 프로젝트 생성하기  (0) 2024.05.05
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함