1-9. CounterContainer 컴포넌트 만들기
이제 컨테이너 컴포넌트를 만들 차례입니다. 컨테이너 컴포넌트를 store 에 연결을 시켜주려면 react-redux
의 connect
함수를 사용해야하는데요, 이 함수의 파라미터로 컴포넌트에 연결시킬 상태와, 액션함수들을 전달해주면, 컴포넌트를 리덕스 스토어에 연결시키는 또 다른 함수를 반환합니다. 이 과정에서 리턴된 함수 안에, 프리젠테이셔널 컴포넌트를 파라미터로 전달해주면 리덕스 스토어에 연결된 컴포넌트가 새로 만들어집니다.
컴포넌트에 연결시킬 상태와 액션함수를 정의할땐 각각 함수를 만들어줘야하는데요. 상태를 연결시킬땐 state, 액션함수를 연결시킬땐 dispatch 를 파라미터로 전달받는 함수를 만들어서 객체를 반환하면 이를 props 로 사용 할 수 있게 됩니다.
한번 예제 코드를 살펴보세요.
src/containers/CounterContainer.js
import Counter from '../components/Counter';
import * as actions from '../actions';
import { connect } from 'react-redux';
// store 안의 state 값을 props 로 연결해줍니다.
const mapStateToProps = (state) => ({
color: state.color,
number: state.number
});
/*
액션 생성자를 사용하여 액션을 생성하고,
해당 액션을 dispatch 하는 함수를 만들은 후, 이를 props 로 연결해줍니다.
*/
const mapDispatchToProps = (dispatch) => ({
onIncrement: () => dispatch(actions.increment()),
onDecrement: () => dispatch(actions.decrement()),
onSetColor: () => {
const color = 'black'; // 임시
dispatch(actions.setColor(color));
}
});
// Counter 컴포넌트의 Container 컴포넌트
// Counter 컴포넌트를 어플리케이션의 데이터 레이어와 묶는 역할을 합니다.
const CounterContainer = connect(
mapStateToProps,
mapDispatchToProps
)(Counter);
export default CounterContainer;
상태를 연결시키는 함수는 mapStateToProps 로, 액션함수를 연결시키는 함수는 mapDispatchToProps 로 만들어서, 이를 connect에 전달해주고, 그렇게 전달받은 함수에 우리가 아까 만든 Contact 컴포넌트를 전달하여 이를 내보냈습니다.
현재 랜덤 색상을 만드는 함수를 아직 만들지 않았는데요, 이 함를 util 디렉토리에 index.js
안에 정의해주세요.
src/utils/index.js
export function getRandomColor() {
const colors = [
'#495057',
'#f03e3e',
'#d6336c',
'#ae3ec9',
'#7048e8',
'#4263eb',
'#1c7cd6',
'#1098ad',
'#0ca678',
'#37b24d',
'#74b816',
'#f59f00',
'#f76707'
];
// 0 부터 12까지 랜덤 숫자
const random = Math.floor(Math.random() * 13);
// 랜덤 색상 반환
return colors[random];
}
이 색상들은 open-color 에서 가져온 색상들입니다.
자, 그 다음, 이 함수 불러온다음에, 아까 mapDispatchToProps 에서 임시로 const color = 'black'
을 한곳에서 호출하세요.
src/containers/CounterContainer.js
import Counter from '../components/Counter';
import * as actions from '../actions';
import { connect } from 'react-redux';
import { getRandomColor } from '../utils';
// store 안의 state 값을 props 로 연결해줍니다.
const mapStateToProps = (state) => ({
color: state.color,
number: state.number
});
/*
액션 생성자를 사용하여 액션을 생성하고,
해당 액션을 dispatch 하는 함수를 만들은 후, 이를 props 로 연결해줍니다.
*/
const mapDispatchToProps = (dispatch) => ({
onIncrement: () => dispatch(actions.increment()),
onDecrement: () => dispatch(actions.decrement()),
onSetColor: () => {
const color = getRandomColor();
dispatch(actions.setColor(color));
}
});
// Counter 컴포넌트의 Container 컴포넌트
// Counter 컴포넌트를 어플리케이션의 데이터 레이어와 묶는 역할을 합니다.
const CounterContainer = connect(
mapStateToProps,
mapDispatchToProps
)(Counter);
export default CounterContainer;
컨테이너 컴포넌트도 다 만들었습니다!
이제 이걸 App.js
에서 불러와서 렌더링해주면 기능이 작동할거에요.
1장에서 구현할 기능은 다 끝났습니다!
마지막으로, 리듀서가 상태가 복잡한 상황을 대비하여, 공부를 위해 우리의 리듀서를 여러개의 리듀서로 쪼개보도록 하겠습니다.