1. 컨테이너 컴포넌트 만들기
이제 컴포넌트에서 리덕스 스토어에 접근하어 원하는 state를 받아 오고, 액션도 디스페치해야 합니다.
리덕스 스토어와 연동되어 있는 컴포넌트를 컨테이너 컴포넌트라고 합니다.
1.1 CounterContainer 만들기
src 디렉토리안에 containers 디렉토리를 생성하고 그 안에 CounterContainer 를 작성합니다.
- containers/CounterContainer.js
import React from "react";
import Counter from "../components/Counter";
const CounterContainer = () => {
return <Counter/>
};
export default CounterContainer;
위 컴포넌트를 리덕스와 연동하려면 react-redux 라이브러리에서 제공하는 connect 함수를 사용해야 합니다.
connect(mapStateToProps, mapDispatchToProps)(연동 컴포넌트)
- mapStateToProps: 리덕스 스토어 안의 상태를 컴포넌트의 props로 넘겨주기 위한 설정 함수입니다.
- mapDispatchToProps: 액션 생성 함수를 컴포넌트의 props로 넘겨주기 위해 사용하는 함수입니다.
connect 함수를 호출하면 또 다른 함수를 반환하는데, 반환된 함수에 컴포넌트를 파라미터로 넣어 주면 리덕스와 연동된 컴포넌트가 만들어 집니다.
- containers/CounterContainer.js
import React from "react";
import { connect } from "react-redux";
import Counter from "../components/Counter";
const CounterContainer = ({ number, increase, decrease }) => {
return (
<Counter number={number} onIncrease={increase} onDecrease={decrease} />
);
};
// 스토어 안의 상태를 props로 넘겨줌
const mapStateToProps = state => ({
number: state.counter.number,
})
// 액션 생성 함수를 props로 넘겨줌
const mapDispatchToProps = dispatch => ({
//임시 함수선언
increase: () => {
console.log('increase');
},
decrease: () => {
console.log('decrease');
},
});
//
export default connect(
mapStateToProps,
mapDispatchToProps,
)(CounterContainer);
mapStateToProps, mapDispatchProps에서 반환하는 객체 내부 값은 컴포넌트의 props로 형태로 전달됩니다.
- mapStateToProps: 현재 스토어가 지니고 있는 state
- mapDispatchProps: store의 내장 함수 dspatch의 파라미터
이제 App.js 파일의 컴포넌트에 작성한 컨테이너를 추가합니다.
- App.js
import React from "react";
import Todos from "./components/Todos";
import CounterContainer from "./containers/CounterContainer";
const App = () => {
return (
<div>
<CounterContainer/>
<hr/>
<Todos/>
</div>
)
}
export default App;
1.2 최종 결과
아래와 같이 +1, -1을 눌렀을때 콘솔에 로그가 잘 찍히나요?.
찍힌다면 이제 로그 대신 액션 객체를 만들어서 디스패치 처리를 할 차례입니다.
- containers/CounterContainer.js
import React from "react";
import { connect } from "react-redux";
import Counter from "../components/Counter";
import { decrease, increase } from "../modules/counter";
const CounterContainer = ({ number, increase, decrease }) => {
return (
<Counter number={number} onIncrease={increase} onDecrease={decrease} />
);
};
// 스토어 안의 상태를 props로 넘겨줌
const mapStateToProps = state => ({
number: state.counter.number,
})
// 액션 생성 함수를 props로 넘겨줌
const mapDispatchToProps = dispatch => ({
increase: () => {
// console.log('increase');
dispatch(increase());
},
decrease: () => {
// console.log('decrease');
dispatch(decrease());
},
});
//
export default connect(
mapStateToProps,
mapDispatchToProps,
)(CounterContainer);
마지막으로 화면에서 다시 버튼을 눌러서 counter 값이 바뀌는지를 확인해 봅시다.
리덕스 개발자도구에서 상태 변화도 같이 확인해 보시면 됩니다.
1.3 소스 최적화
- containers/CounterContainer.js
import React from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import Counter from "../components/Counter";
import { decrease, increase } from "../modules/counter";
const CounterContainer = ({ number, increase, decrease }) => {
return (
<Counter number={number} onIncrease={increase} onDecrease={decrease} />
);
};
// 소스 최적화
export default connect(
state => ({
number: state.counter.number,
}),
dispatch =>
bindActionCreators(
{
increase,
decrease,
},
dispatch,
),
)(CounterContainer);
이제 마지막으로 위와 같이 bindActionCreators를 통해서 소스코드를 줄여봅시다.
리덕스에서 제공하는 해당함수로 불필요한 소스를 줄일 수 있습니다.
- containers/CounterContainer.js
import React from "react";
import { connect } from "react-redux";
import Counter from "../components/Counter";
import { decrease, increase } from "../modules/counter";
const CounterContainer = ({ number, increase, decrease }) => {
return (
<Counter number={number} onIncrease={increase} onDecrease={decrease} />
);
};
// 소스 최적화
export default connect(
state => ({
number: state.counter.number,
}),
{
increase,
decrease,
},
)(CounterContainer);
마지막으로 두 번째 파라미터를 아예 객체 형태로 connect 내부에 넣어 주면 내부적으로
bindActionCreators 처리작업도 대신 해줄 수 있습니다.
이전 소스와 비교해보고 소스가 얼마나 줄어 들었는지 비교해볼 수 있습니다.
이제 이전과 동일하게 기능이 작동하는지도 확인해 보세요.
'프론트엔드 > React' 카테고리의 다른 글
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[8] (0) | 2022.04.10 |
---|---|
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[7] (0) | 2022.04.10 |
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[5] (0) | 2022.04.10 |
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[4] (0) | 2022.04.09 |
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[3] (0) | 2022.04.07 |