How to apply Redux in React App

SooYoung Kim·2020년 3월 30일
0
post-thumbnail

P.S. 아래의 글은 이 링크를 많이 참조했다.

전체 구조

// index.js
import React from "react";
import ReactDOM from "react-dom";

import { Provider } from "react-redux";
import store from "./redux/store";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <TodoApp />
  </Provider>,
  rootElement
);
// App.js
import React from 'react';
import { connect } from "react-redux";       // connect함수 불러오기
import * as actions from "./store/reducer";  // 액션 불러오기
import { bindActionCreators } from "redux";  // mapDispatchToProps를 좀더 쉽게 하기 위해 사용

const App = ({ number, actions }) => {
	return (
		<div>
			...actions.action1 //액션 사용
        	...actions.action2 //액션 사용
        	...actions.action3 //액션 사용
		</div>
	);
}

const mapStateToProps = state => ({
	number: state.number
});

// version 1
const mapDispatchToProps = dispatch => ({
	increase: number => dispatch(increase(number)),
	decrease: number => dispatch(decrease(number))
}); 

// version 2
// dispatch와 action들을 묶어줘야 하는데, 아래처럼 하면 아무리 action이 많아도
// 한방에 묶을 수 있다.
const mapDispatchToProps = dispatch => ({
	counter: bindActionCreators(counter, dispatch)
});

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

위 코드를 간략하게 설명하자면 'react-redux'모듈에서 'Provider'라는 컴포넌트를 가져온다. 그리고 그걸 App 컴포넌트 주위로 감싸주고, store를 넘겨준다.

App.js에서 보이듯이 App 컴포넌트는 state에서 나온 number와 action들의 묶음인 actions를 인자로 받는다. 그리고 함수 컴포넌트 안에서 사용한다. 이렇게 컴포넌트 안에서 store에서 온 number나 reducer에서 온 action들을 사용하려면 state , actions , component 이 세가지를 연결시켜 줘야 한다. 그 역할을 하는 것이 맨 마지막 줄의 connect 함수이다. connect함수에 인자로 넘겨지는 두 함수는 아래에서 설명하고자 한다.

mapStateToProps 함수

mapStateToProps함수는 store에서 필요한 데이터 부분을 선택하는 역할을 한다. 이름이 길어서 사람들은 자주 mapState라고 부른다. mapStateToProps함수는 아래 두 개의 특징을 가지고 있다.

  1. store에 있는 state가 바뀔 때마다 호출된다.
  2. store에 있는 state 전체를 인자로 받고, component에 필요한 데이터를 객체의 형태로 return한다.

이 함수는 connect함수의 첫 번째 인자로 들어간다. 함수 스스로는 기본적으로 store에 저장된 state 전체를 첫 번째 인자로 받으며, 선택적으로 ownProps라는 인자를 받을 수 있다. 이것은 store에 들어가있는 state말고, 부모 컴포넌트에서 자식 컴포넌트로, 명시적으로 넘겨준 정보가 있을 경우, 또한 그것을 넘겨줘서 작업해야 하는 경우 ownProps라고 인자를 넘겨주면 된다. 아래는 예시이다.

// Todo.js

function mapStateToProps(state, ownProps) {
  const { visibilityFilter } = state
  const { id } = ownProps
  const todo = getTodoById(state, id)
  return { todo, visibilityFilter } 
}
/*
return의 결과는 다음 객체와 같을 것이다.
{
	id: ownProps.id,
	todos: state.todos,
	filter: state.visibilityFilter
}
*/

// 나중에 위 컴포넌트를 부를 때 부모 컴포넌트는 자식 컴포넌트에게 id 값을 넘겨주어야 한다.
<Parent>
    <Child id={123} />
</Parent>

mapDispatchToProps 함수

mapDispatchToProps함수는 action들을 store에 dispatch함수로 붙이기 위한 것이다. connect함수의 두번째 인자로 들어간다. 마찬가지로 이름이 길어 슬픈 함수로, 사람들은 자주 mapDispatch라고 줄여 부른다.

mapDispatchToProps함수는 하나의 함수를 넘겨주는데, 그 함수는 action들이 호출될 때 dispatch해주는 역할을 한다. 이 함수는 component의 props로 넘겨진다. 그럼 component에서 사용할 때는 action()의 형태로 바로 사용할 수 있다.

react-redux에서 제공하는 또 하나의 방법은 mapDisPatch함수를 적어주지 않는 것이다. 그렇게 되면 mapDispatch를 받지 못한 connect함수는 자동으로 props.dispatch를 component에 넘겨준다. 그럼 component에서 action을 사용할 때는 dispatch({ type: action.type })의 형식으로 사용하면 된다.

// version 1
const mapDispatchToProps = dispatch => ({
	increase: number => dispatch(increase(number)),
	decrease: number => dispatch(decrease(number))
}); 

// version 2
// dispatch와 action들을 묶어줘야 하는데, 아래처럼 하면 아무리 action이 많아도
// 한방에 묶을 수 있다.
const mapDispatchToProps = dispatch => ({
	counter: bindActionCreators(counter, dispatch)
});
profile
Enjoy my coding

0개의 댓글