# 247 [udemy React 완벽 가이드 노트] 클래스 기반 컴포넌트가 있는 리덕스
클래스 기반 컴포넌트를 만들자.
그리고 메서드 incrementHandler와 decrementHandler와
toggleCounterHandler를 추가한다.
어떻게 리덕스에 접근할 수 있는가?
class Counter2 extends Component {
incrementHandler() {
}
decrementHandler() {
}
toggleCounterHandler() {
}
render() {
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
<div className={classes.value}>{counter}</div>
<div>
<button onClick={this.incrementHandler}>Increment</button>
<button onClick={this.decrementHandler}>Decrement</button>
</div>
<button onClick={this.toggleCounterHandler}>Toggle Counter</button>
</main>
);
}
}
함수 컴포넌트에서는 useDispatch와 useSelector 훅을 사용했었다.
훅은 클래스 컴포넌트에서는 사용할 수 없다.
Connect 함수
react-redux는 connect 함수도 export한다.
connect 함수는 클래스 기반 컴포넌트를 리덕스에 연결하는 데 도움을 준다.
이것은 함수 컴포넌트에서도 사용할 수 있다.
그러나 함수 컴포넌트에서는 훅을 사용하는 것들이 더 편리하다.
사용방법
export default에 connect를 호출한다.
connect가 실행되면 새 함수를 리턴한다.
그러면 컴포넌트를 변수로 리턴된 함수로 보내어 다시 실행된다.
export default connect()(Counter);
왜 이렇게 하는걸까?
이걸 실행할 때 연결하기 위해서 뭔가 보내기도 하는 것이다.
커넥트는 두개의 함수로 된 인자가 있어야 한다.
첫 번째 인자는
컴포넌트에 받아질
리덕스 state를 프롭으로 맵하는 함수다.
리덕스 state를 받아서 객체를 리턴하고
받는 컴포넌트에서(여기서는 Counter) 키를 프랍으로 사용할 수 있다.
키의 값은 리덕스 state로 들어가는 로직이다.
const mapStateToProps = state => {
return {
counter: state.counter
}
}
리덕스 state에서 counter값을 선택,
그 값을 카운터 프롭에 묶는다.
useSelector에서 한 것과 비슷하다.
state를 받고 counter를 받기 위해 state로 들어간다.
const counter = useSelector(state => state.counter);
훅이 아니라 커넥트 함수일 뿐, 두가지는 같은 일을 하고 있다.
이제 커넥트로 보내는 첫 번째 인자로 mapStateToProps를 보낸다.
export default connect(mapStateToProps)(Counter);
두 번째 인자는
useDispatch와 같은 역할을 하는 또다른 함수다.
디스패치 함수를 프랍에 저장하는 것이다.
Counter컴포넌트에 특정 프랍을 입력하고,
액션을 리덕스 스토어에 디스패치 해
함수로 실행할 수 있게 한다.
const mapDispatchToProps = () => {
}
여기서 자동으로 mapStateToProps처럼
디스패치 함수를 인자로 받는다.
mapDispatchToProps함수는
리덕스가 우리를 위해 실행 해 줄 것이다.
이 함수는 객체를 return하는데,
키는 프랍네임인데
컴포넌트에서 사용할 수 있다.
밸류는 다른 함수인데
디스패치를 입력하여 액션을 설정한다.
const mapDispatchToProps = dispatch => {
return {
increment: ()=> dispatch({type: 'increment'}),
decrement: ()=> dispatch({type: 'decrement'})
};
이렇게 되면 Counter 컴포넌트에서 increment 프롭이 있어 사용할 수 있게 된다.
increment 프롭은 함수를 저장하고 있고,
컴포넌트 내부에서 이 함수를 실행할 수 있다.
그러면 dispatch를 호출하여
{type: 'increment'}
위의 액션을 dispatch하게 된다.
이 함수가 connect에 보낸 두 번째 인자다.
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
이렇게 두가지를 포인터로 보내주면(실행 아님)
react-redux가 우릴위해 실행하게 될 것이다.
커넥트를 사용하면
react-redux가 subscription을 설정하고 관리해 줄 것이다.
class Counter2 extends Component {
incrementHandler() {
this.props.increment();
}
decrementHandler() {
this.props.decrement();
}
incrementHandler 메서드에서 this.props.increment로 실행할 수 있다.
Counter.js파일
import { Component } from "react";
import { useSelector, useDispatch, connect } from "react-redux";
import classes from "./Counter.module.css";
class Counter extends Component {
incrementHandler() {
this.props.increment();
}
decrementHandler() {
this.props.decrement();
}
toggleCounterHandler() {}
render() {
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
<div className={classes.value}>{this.props.counter}</div>
<div>
<button onClick={this.incrementHandler.bind(this)}>Increment</button>
<button onClick={this.decrementHandler.bind(this)}>Decrement</button>
</div>
<button onClick={this.toggleCounterHandler}>Toggle Counter</button>
</main>
);
}
}
const mapStateToProps = state => {
return {
counter: state.counter,
};
};
const mapDispatchToProps = dispatch => {
return {
increment: () => dispatch({ type: "increment" }),
decrement: () => dispatch({ type: "decrement" }),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter);