: 개발의 복잡성을 낮춰주는 시스템
React | Redux |
---|---|
Component를 이용하여 체계적인 Application을 만들 수 있다 | State 중앙관리를 통해 데이터의 변형 가능성을 낮춰준다. |
집집마다 소문이 퍼지는 것처럼 변화 발생 시 연결된 모든 컴포넌트로 전달 | 언론사에서 방송하는 것처럼 변화 발생 시 연결 여부와 무관 모든 컴포넌트로 전달 |
1. createStore : store.js
store 생성하기
import { createStore } from "redux";
// redux의 API createStore를 import
export default createStore(
function (state, action) { return state; },
// createStore의 첫번째 인자 reducer는 기본적으로 state를 반환
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__());
// devTools 활성화 코드는 createStore의 두번째 인자로 삽입했다
2. AddNum.js
+버튼을 클릭했을 때 store의 state를 변경하기
import store from "../store";
(...)
<input
type="button"
value="+"
onClick={function () {
store.dispatch({ type: "INCREMENT", size: this.state.size });
// dispatch action
// {type:"INCREMENT", size:this.state.size}
}.bind(this)}
/>
3. State 변경 store.js
이제 devTools에서 state값의 변경을 확인할 수 있다
if (state === undefined) { return { number: 0 } }
if (action.type === "INCREMENT") {
return { ...state, number: state.number + action.size } }
// state의 property만 변형시키기
return state;
4-1. State 변경을 Component에 적용하기 DisplayNumber.js
✔︎ 아직은 store가 변경되어도 render가 다시 될 근거가 없다!
import React, { Component } from "react";
import store from "../store";
class DisplayNumber extends Component {
state = { number: store.getState().number };
// state = store의 state 설정
render() {
return (
<DisplayNumberFrame>
<h1>Display Part</h1>
<input type="text" value={this.state.number} readOnly />
</DisplayNumberFrame>
);
}
}
export default DisplayNumber;
4-2. State 변경을 화면에 적용하기 (re-render)
✔︎ subscribe : 이제 부모 요소에서 props로 전달할 필요가 없어졌다 !
class DisplayNumber extends Component {
constructor(props) {
super(props);
// store의 state가 변경되면 function을 실행한다
store.subscribe(
function () {
this.setState({ number: store.getState().number });
// this.state.number를 store의 number 값으로 업데이트
}.bind(this)
);
}
state = { number: store.getState().number };
(...)
: Redux에 종속되면서 재사용할 수 없는 Component가 되었다!
어떻게 해결하면 좋을까?
기존의 Component를 Wrapper로 감싸고 아래와 같이 구분한다.
Wrapper : Container Component ( redux 적용 )
기존의 Component : Presentational Component
( Wrapper - Component가 1:1 match될 필요는 없다 ! )
5. Container Component
기존의 Component를 import → 그대로 export 하는 Wrapper 생성
: 그러나 Container Component를 도입하면서 코드가 많아졌다 !
1. Container에 dispatch code를 추가해야 한다.
2. Store의 상태 전달 시 re-render를 위해 subscribe code를 추가해야 한다.
3. Component 내부에서 상태 전달 시 Container를 거치는 props code를 추가해야 한다.
Root Comp- → Container Comp-(props) → Presentational Comp-(props)
어떻게 해결하면 좋을까?
react-redux의 method인 connect와 provider를 사용한다
( container component )
Connect : Container Component를 export
( 최상위 index.js )
Provider : store를 공급
6. Provider & Connect
7. mapStateToProps & mapDispatchToProps
State와 Dispatch를 전달하려면 connect API의 인자로 각각의 함수를 전달해야 한다.
mapStateToProps()
Redux의 State를 React Props로 전달
mapReduxStateToReactProps(store.getState(), this.props)
mapDispatchToProps()
Redux의 Dispatch를 React Props로 전달
mapReduxDispatchToReactProps(store.dispatch, this.props)
✎ connect() API 가 호출될 때 일어나는 일