본문 바로가기

Libraries/Redux

[Redux] Redux와 React를 연동하기

728x90

 

   목차 

1. Container
2. react-redux
3. provider
4. mapStateToProps()
5. mapDispatchToProps()
6. connect()
7. 가장 많이 하는 실수
8. Redux와 React 연동 과정

 

 

React와 Redux를 연동하기 위한 개념들을 알아보자!

 

 


 

 

 

 1. Container 

 

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

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

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

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

 

 

 

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

 

 


 

 

 2. react-redux 

 

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

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

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

 

 


 

 

 3.  provider  

 

Context의 Provide는 value를 prop으로 가지는 반면, 

// Context의 Provider Component 사용 예시

function App(props) {
	const [value, setValue] = useState({ something: 'something' });
    return (
		<MyContext.Provider value={value}>
		<Toolbar />
		<MyContext.Provider />
);
}

 

react-redux의 Provider는 store를 prop으로 가진다. (여기서 store는 Redux Store를 의미함)

리액트의 Context API 처럼, 최상위 컴포넌트인 App 컴포넌트 Provider로 감싸줘서, App 컴포넌트가 리덕스 Store에 접근할 수 있게 해준다.

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import { App } from './App'
import createStore from './createReduxStore';

const store = createStore();

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

 

 


 

 

 4. 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,
	}
}

 

 

 


 

 

 5. 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,
			});
		},
	}
}

 

 

 


 

 

 6. connect() 

 

Redux와 React 컴포넌트를 연결시켜주는 역할 (→ 둘을 연결하면 Container가 된다!)

실제로 Container를 만드는 역할을 수행한다.

react-redux 패키지에서 제공하는 함수로, 바로 호출해서 사용할 수 있다.

connect() 함수는 Wrapper Function을 리턴하고,
여기에 어떤 리액트 컴포넌트든지 파라미터로 넣어서 호출하면 Redux에 연결시킬 수 있다.

 

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

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

 

 

connect() 함수 예시

 

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;

 

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

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

 

 


 

 

 7.  가장 많이 하는 실수 

 

1) 기존 React의 <Counter /> 컴포넌트를 import해서 렌더링 하는 코드 (잘못된 방법)

import Counter from './components/Counter';

function MainPage() {
	return (
    	<Counter />
    )
}

 

2) <Counter /> 컴포넌트를 Redux에 connect 시킨 <CounterContainer />를 import해서 렌더링 하는 코드 (올바른 방법)

import CounterCountainer from './redux/containers/CounterCountainer';

function MainPage() {
	return (
    	<CounterCountainer />
    )
}

 

(2)의 방법과 같이 하는 이유는, 리덕스에 있는 state나 action을 dispatch하는 함수를 사용하기 위함인데, 리덕스에 연결된 container 컴포넌트를 사용하지 않고 그냥 기존의 React 컴포넌트를 사용하면 에러가 발생할 수 있기 때문이다.

따라서 꼭 connect() 된 컴포넌트를 사용해야한다! 그리고 여기서 connect()된 컴포넌트가 바로 container라는 걸 잊지말자!

 

 


 

 

 8. Redux와 React 연동 과정 

 

1) Redux Store 생성

2) Redux Action Type 정의Action CreatorReducer 구현

3) React Component 구현

4) Container 만들기

     → mapStateToProps()

    mapDispatchToProps()

    connect()

5) Provider를 사용해 store 전달하기 (Higher Order Component, HOC)

6) Container Component 렌더링

 

 

 

728x90

'Libraries > Redux' 카테고리의 다른 글

[Redux] Reducer  (0) 2025.01.12
[Redux] Action  (0) 2025.01.12
[Redux] Dispatch  (0) 2025.01.01
[Redux] Store  (0) 2025.01.01
[Redux] Redux의 개념, 탄생 배경, 3가지 원칙, Context Api와의 비교  (0) 2024.12.10