[Redux] Container

Dodam·2024년 1월 28일
0

[Redux]

목록 보기
6/11
post-thumbnail

Container

Container는 Redux를 리액트에 연동했을 때 사용하는 개념이다.
(Redux에는 Container라는 개념이 없음)

여기서 Container는 Container Component의 줄임말이며, 컴포넌트는 리액트 컴포넌트를 의미한다.

결국, Container는 Redux의 일부 state와 dispatch를 포함하는 리액트 컴포넌트이다.

Container의 정의를 그림으로 나타내면 다음과 같다.

즉, 요약하면 Component는 Redux에 대해서 모르는 일반적인 리액트 컴포넌트를 의미하고,
Container는 Redux와 연결된 리액트 컴포넌트를 의미한다.

react-redux

Container를 만들기 위해서는 리액트 컴포넌트와 Redux를 연결해야 하는데, 이때 react-redux라는 라이브러리를 사용할 수 있다.

Redux에는 다양한 Binding Library(Redux와 React를 연동)들이 있는데,
그 중 하나가 바로 react-redux이다.

  • Binding Library : 어떤 라이브러리를 특정 환경에서 사용하기 위해, 그 환경과 라이브러리를 중간에서 묶어주는 역할을 하는 라이브러리. 줄여서 Binding이라고도 부른다.

react-redux의 주요 API

Provider

  • Provider의 하위 컴포넌트들이 리덕스 Store에 접근할 수 있게 해준다.

  • 리액트의 Context API 처럼, 최상위 컴포넌트인 App 컴포넌트를 Provider로 감싸준다.

    • Context API
      리덕스는 Store에 있는 State들을 컴포넌트로 곧바로 전달할 수 있다. 이렇게 데이터를 전달하는 통로는 리액트의 Context API 이다.
      리덕스는 내부적으로 이 Context API를 사용하여, 컴포넌트 트리를 따라 Store에 있는 데이터들을 전달한다.
      Context의 데이터를 하위 컴포넌트로 전달하려면 Provider로 감싸줘야 한다.

  • Context의 Provide는 valueprop으로 가지는 반면, react-redux의 Provider는 storeprop으로 가진다. (여기서 store는 Redux Store를 의미함)
import { Provider } from 'react-redux';
import createStore from './createReduxStore';
const store = createStore();

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

mapStateToProps()

  • state를 타겟 리액트 컴포넌트의 props로 연결시켜주는 역할을 하는 함수
function mapStateToProps(state, ownProps?)

// state: 전체 state에서 연결할 컴포넌트에 필요한 state만 추출해서 mapping
// ownProps(옵션): mapping시킬 타겟 컴포넌트가 가지고 있는 자체 prop

  • 타겟 컴포넌트에서 필요로 하는 state만을 꺼내서 일반적인 JavaScript 객체 형태로 리턴해야 한다.
function mapStateToProps(state) {
	const { posts, comments } = state;

	return {
		post: posts,
		comments: comments;
	}
}

  • ownProps를 사용해서 state를 추출하는 예시
// ownProps에 들어있는 postId 값을 사용해서 posts에서 해당되는 아이디 값을 가진 post를 찾아 해당 post만을 리턴

function mapStateToProps(state, ownProps) {
	const { posts, comments } = state;

	const targetPost = posts.find((post) => {
		return post.id === ownProps.postId;
	});

	return {
		post: targetPost,
	}
}



mapDispatchToProps()

  • 리덕스 dispatch를 리액트 컴포넌트의 props로 연결시켜주는 역할을 하는 함수
  • 자바스크립트 객체를 리턴해야 한다.
  • dispatch와 ownProps(옵션)를 파라미터로 가진다.

아래 코드를 보면, Action(카운트 증가 및 감소)을 Dispatch하기 위한 함수를 만들고, 이 함수를 객체 형태로 만들어서 리턴한다.

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

  • ownProps를 사용해서 Action 객체를 만들고, dispatch하는 예시
function mapDispatchToProps (dispatch, ownPoprs) {
	return {
		increaseCount: () => {
			dispatch({ 
				type: 'INCREMENT_COUNT',
				counterId: ownProps.counterId,
			});
		},
		decreaseCount: () => {
			dispatch({ 
				type: 'DECREASE_COUNT',
				counterId: ownProps.counterId,
			});
		},
	}
}



connect()

  • Redux와 React 컴포넌트를 연결시켜주는 역할 (→ 둘을 연결하면 Container)
  • 실제로 Container를 만드는 역할을 수행
  • react-redux 패키지에서 제공하는 함수로, 바로 호출해서 사용할 수 있다.
  • connect() 함수는 Wrapper Function을 리턴하고,
    여기에 어떤 리액트 컴포넌트든지 파라미터로 넣어서 호출하면 Redux에 연결시킬 수 있다.
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

// mergeProps: 연결하는 컴포넌트에 최종적으로 전달될 props를 결정하는 함수
// options: 추가적인 옵션들을 사용하기 위한 객체

connect() 함수 예시
Step 1 :
mapStateToProps() 함수와 mapDispatchToProps() 함수를 만들고,
connect() 함수의 파라미터로 넣어서 호출한다. 이렇게 호출하면 Wrapper Function이 리턴되는데,
이 Wrapper Function을 사용하면 어떤 리액트 컴포넌트든지 Container로 만들 수 있다.

Step 2 :
Wrapper Function을 통해 Redux와 Counter 컴포넌트를 연결하면 Container Component가 리턴된다.

import Counter from '../components/Counter';

function mapStateToProps(state) {
	return {
		count: state.count,
	}
}

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

// Step 1: 리액트 컴포넌트를 파라미터로 넣어서 호출하면 Redux에 연결시킬 수 있는 Wrapper Function을 리턴
const connectCount = connect(mapStateToProps, mapDispatchToProps);

// Step 2: Redux와 연결된 Container 컴포넌트를 리턴
const CounterContainer = connectCount(Counter);

// Step 1, 2를 동시에 처리하는 방식
const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(Counter);
export default CounterContainer;



요약

  • Container : Redux와 연결되어 있는 React 컴포넌트

  • react-redux

    • redux와 React를 연동해서 사용할 수 있게 해주는 공식 Binding Library

    • 주요 API

      • Provider : 하위 컴포넌트들이 Redux Store에 접근할 수 있게 해주는 상위 컴포넌트
      • mapStateToProps() : Redux State를 타겟 React 컴포넌트의 props로 연결시켜주는 함수
      • mapDispatchToProps() : Redux dispatch를 타겟 React 컴포넌트의 props로 연결
      • connect() : Redux와 React 컴포넌트를 연결시켜주는 역할을 하는 함수

  • Redux와 React 연동 과정

    1. Redux Store 생성
    2. Redux Action Type 정의 및 Action Creator와 Reducer 구현
    3. React Component 구현
    4. Container 만들기
    5. Provider를 사용해 store 전달하기
    6. Container Component 렌더링
profile
Good things take time

0개의 댓글