컨테이터 컴포넌트를 만드는 방법중 하나. 클래스형 컴포넌트로 작성을 하게되는 경우에는 Hooks를 사용하지 못하기 때문에 connect 함수를 사요해야한다.
2019년 이전에 작성된 리덕스와 연동된 컴포넌트들은 connect함수로 작성되었는데. useSelector
,useDispatch
같은 Hooks
가 등장했기 때문에 요즘엔 많이 사용되지 않는다.
만약 예전에 만들어진 리액트 프로젝트를 유지보수하게 될 때에는 connect 함수를 접할수도 있다.
Higher-Order Componenet를 뜻하며, 리액트 컴포넌트를 개발하는 패턴으로써, 컴포넌트의 로직을 재활용 할때 유용한 패턴이다. 특정 함수 혹은 값을 props로 받아와서 사용하고싶은 경우에 이러한 패턴을 사용한다. Hook
이 도입되기 전에 자주 사용되었으며 도임 후에는 많이 사용되지않는다.
함수는 리덕스 스토어 안에 있는 상태를 props로 넣어줄수도 있고 액션을 디스패치하는 함수를 props로 넣어줄 수도 있다.
containers/CounterContainer
// mapStateToProps 는 리덕스 스토어의 상태를 조회해서 어떤 것들을 props 로 넣어줄지 정의한다.
// 현재 리덕스 상태를 파라미터로 받아온다..
const mapStateToProps = state => ({
number: state.counter.number,
diff: state.counter.diff
});
// mapDispatchToProps 는 액션을 디스패치하는 함수를 만들어서 props로 넣어준다
// dispatch 를 파라미터로 받아온다.
const mapDispatchToProps = dispatch => ({
onIncrease: () => dispatch(increase()),
onDecrease: () => dispatch(decrease()),
onSetDiff: diff => dispatch(setDiff(diff))
});
// connect 함수에는 mapStateToProps, mapDispatchToProps 를 인자로 넣는다.
export default connect(
mapStateToProps,
mapDispatchToProps
)(CounterContainer);
/* 위 코드는 다음과 동일
const enhance = connect(mapStateToProps, mapDispatchToProps);
export defualt enhance(CounterContainer);
*/
mapStateToProps
는 컴포넌트에 props 넣어줄 리덕스 스토어 상태에 관련된 함수이고, mapDispatchToProps
는 컴포넌트에 props로 넣어줄 액션을 디스패치하는 함수들에 관련된 함수이다. redux라이브러리에 내장된 bindActionCreators
라는 함수를 사용해서 리팩토링 할 수 있다.
bindActionCreators(
{
increase,
decrease,
setDiff
},
dispatch
);
connect
함수에서는 mapDispatchToProps
가 함수가 아니라 객체형태일때는 bindActionCreators
를 대신 호출해준다.
const mapDispatchToProps = {
increase,
decrease,
setDiff
};
mapStateToProps
와 mapDispatchToProps
를 따로 선언하지 않고 connect
함수를 사용 할 때 인자쪽에서 익명함수로 바로 만들어서 사용하면 코드가 깔끔해진다.
containers/TodosContainer
import React, { useCallback } from 'react';
import { connect } from 'react-redux';
import Todos from '../components/Todos';
import { addTodo, toggleTodo } from '../modules/todos';
function TodosContainer({ todos, addTodo, toggleTodo }) {
const onCreate = text => addTodo(text);
const onToggle = useCallback(id => toggleTodo(id), [toggleTodo]); // 최적화를 위해 useCallback 사용
return <Todos todos={todos} onCreate={onCreate} onToggle={onToggle} />;
}
export default connect(
state => ({ todos: state.todos }),
{
addTodo,
toggleTodo
}
)(TodosContainer);
mapStateToProps
에서는 두번째 파라미터 ownProps
를 받아올 수 있다. 생략해도 되는파라미터이지만 이값은 컨테이너 컴포넌트를 렌더링할 때 직접 넣어주는 props를 가르킨다.
예를 들어서 <CounterContainer myValue={1} />
이라고 하면 {myValue: 1}
값이 ownProps
가 된다.
이런 방식으로도 활용 가능하다.
const mapStateToProps = (state, ownProps) => ({
todo: state.todos[ownProps.id]
})
mergeProps
는 connect
함수의 세번째 파라미터이고 생략 가능한 파라미터이다. 컴포넌트가 실제로 전달받게 될 props
를 정의한다.
(stateProps, dispatchProps, ownProps) => Object
connect
함수를 사용 할때 컨테이터 컴포넌트가 어떻게 동작할지에 대한 옵션을 설정할수 있다. 생갹해도 되는 파라미터이며, 이 옵션을 통해서 Context 커스터마이징,최적화를 위한 비교작업 커스터 마이징 및 ref관련 작업을 할 수 있다. 자세한 정보는 링크를 참조
https://react-redux.js.org/api/connect#options-object