[Redux]react-redux 생활코딩 실습 2

chaewon Im·2021년 12월 22일
0

공부 기록✏️

목록 보기
2/15
post-thumbnail

⚛️ react-redux 생활코딩 강의 학습내용 정리 2

저번에 구현한 컴포넌트는 store에 종속성이 높아서 재사용이 어렵다는 문제가 있었다.
이를 해결하기 위해 AddNumber 컴포넌트는 store의 존재를 모르는 컴포넌트로 만들고(presentational component), 이를 감싸는 컨테이터 컴포넌트를 만들어 종속성 문제를 해결한다.

  • presentational componet : 화면에 출력하는 일만 하게 됨
  • container component : store에 관한 종속되는 일들을 처리

<변경된 구조>

<AddNumberRoot>
  <container component (./containers/AddNumber)>//컨테이너
    <presentational component (./components/AddNumber)> //원래 컴포넌트
  </container component>
</AddNumberRoot>

기존 형태에서 container component가 끼어든 형태


1. AddNumber.jsx 컴포넌트 종속성 제거

// ./components/AddNumber.jsx

export default class AddNumber extends Component{
  state = {size:1}

  render(){
    return(
      <div>
        <h1>Add Number</h1>

        <input type="button" value="+" onClick={function(){
          this.props.onClick(this.state.size)
        }.bind(this)}/>

        <input type="text" value={this.state.size} onChange={function(e){
          this.setState({size:Number(e.target.value)})
        }.bind(this)}/>
      </div>
    )
  }
}
//./containers/AddNumber.jsx

import AddNumber from '../components/AddNumber'
import React,{Component} from 'react'
import store from '../store'

export default class extends Component{
    render(){
        return <AddNumber onClick={function(size){
            store.dispatch({type:'INCREMENT',size:size})
        }.bind(this)}></AddNumber>
    }
}

기존의 AddNumber 컴포넌트에서 onclick이벤트가 발생하면, size 값을 인자로 전달받아 redux에 값을 전달하는 작업을 진행한다. 기존의 AddNumber 컴포넌트는 redux와 직접적으로 값을 주고받지 않게 되면서 종속성이 사라진다.

2. DisplayNumber.jsx 컴포넌트 종속성 제거

같은 방식으로 DisplayNumber 컴포넌트도 컨테이너와 프레젠테이셔널 컴포넌트 두가지로 분리하여 컨테이너 컴포넌트에서 store의 값을 가져오도록 변경했다.

// ./containers/DisplayNumber.jsx
import DisplayNumber from '../components/DisplayNumber'
import React,{Component} from 'react'
import store from '../store'

export default class extends Component{
    state = {number:store.getState().number}
    constructor(props){
        super(props);
        store.subscribe(function(){
            this.setState({number:store.getState().number});
        }.bind(this));
    }

    render(){
        return <DisplayNumber number={this.state.number}></DisplayNumber>
    }
}
// ./components/DisplayNumber.jsx
export default class DisplayNumber extends Component{ 
    render(){
        return(
        <div>
            <h1>Display Number</h1>
            <input type="text" value={this.props.number} readOnly/>
        </div>
        )
    }
}

컨테이너 컴포넌트에서 number의 값을 store에서 가져오고, 프레젠테이셔널 컴포넌트로 props를 통해 값을 전달한다. 이렇게 되면 프레젠테이셔널 컴포넌트는 값을 받아 출력만 하는 역할을 하고, redux와의 종속성은 사라진다.

  • 왼쪽 : container component
  • 오른쪽 : presentational componet

⚠️ 문제점 : 이렇게 하면 컨테이너/프레젠테이셔널 컴포넌트 역할이 나뉘면서 처리해야 할 파일들이 엄청 많아진다. 또, 데이터를 전달할 때 props도 여러번 이용해야하는 건 똑같다.

이를 해결하기 위해 나온 react redux를 다음 글에서 정리.

profile
빙글빙글 FE 개발자

0개의 댓글