React Redux

LEE JIYUN·2020년 8월 23일
0

React와 Redux

: 개발의 복잡성을 낮춰주는 시스템

ReactRedux
Component를 이용하여 체계적인 Application을 만들 수 있다State 중앙관리를 통해 데이터의 변형 가능성을 낮춰준다.
집집마다 소문이 퍼지는 것처럼
변화 발생 시 연결된 모든 컴포넌트로 전달
언론사에서 방송하는 것처럼
변화 발생 시 연결 여부와 무관 모든 컴포넌트로 전달

Counter App with Redux

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의 StateReact Props로 전달

mapReduxStateToReactProps(store.getState(), this.props)

mapDispatchToProps()

Redux의 DispatchReact Props로 전달

mapReduxDispatchToReactProps(store.dispatch, this.props)

✎ connect() API 가 호출될 때 일어나는 일

0개의 댓글