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

chaewon Im·2021년 12월 22일
0

공부 기록✏️

목록 보기
3/15
post-thumbnail

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

1.Redux 없이 구현한 React App


Root에서 AddNumberRoot->AddNumber까지 props를 통해 number state를 전달하고, AddNumber에서 일어난 버튼 클릭 이벤트를 AddNumberRoot 컴포넌트로 전달하고, 또 이를 AddNumberRoot에서 App.js로 전달한다. App.js에서 이벤트 함수를 적용하면 바뀐 숫자가 다시 DisplayNumberRoot->DisplayNumber 순서로 props를 통해 전달된다.

이런 방식은 컴포넌트의 수가 적으면 문제가 크지 않겠지만, 관리해야 할 컴포넌트의 수가 많아지고 프로그램 사이즈가 커지면 어마어마하게 불편한 문제가 된다.(당장 이런 컴포넌트가 100개만 된다고 해도..😱)

2.Redux로 구현한 React App

redux를 이용하면 이렇게 props로 기이이일게 연결된 컴포넌트간의 연결을 한방에 해결 가능하다.

1)store 생성

//store.js
import {createStore} from 'redux'

export default createStore(function(state,action){
    return state;
})

redux의 createStore api를 이용해 store를 생성한다. 이 때 function은 reducer이고, state와 action을 인자로 준다. reducer는 이 안에서 액션에 따라 새로운 state를 만들고 이 새로운 state를 리턴한다.

2)AddNumber 이벤트 변경

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

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

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

        <input type="button" value="+" onClick={function(){
          store.dispatch({type:'INCREMENT',size: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>
    )
  }
}

기존: button을 클릭하면 props로 부모 컴포넌트로 이벤트를 전달하고, 부모 컴포넌트에서 숫자를 변경했음.

button을 클릭하면 dispatch를 통해 액션의 type과 전달할 state를 담아 리듀서로 보낸다.

//store.js
export default createStore(function(state,action){//여기 이 function이 리듀서라고 생각
    if(state === undefined){
        //아직 정의되지 않은 상태, 최초의 상태
        return {number:0}
    }
    if(action.type === 'INCREMENT'){
        return {...state, number:state.number + action.size}
    }
    return state; //리듀서는 state를 뱉는다
},window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)

다음과 같이 store에 코드를 추가했다. action의 타입을 지정하고, 해당 타입의 액션이 일어나면 다음과 같이 store의 state에 dispatch에서 전달받은 size를 더해 return한다. 그러면 state의 값이 변경된다.

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

export default class DisplayNumber extends Component{
    state = {number:store.getState().number}
    constructor(props){
        super(props);
        store.subscribe(function(){
            this.setState({number:store.getState().number});
        }.bind(this));
    }
    render(){
        return(
        <div>
            <h1>Display Number</h1>
            <input type="text" value={this.state.number} readOnly/>
        </div>
        )
    }
}

DisplayNumber 컴포넌트에서는 기존에는 상위 컴포넌트에서 props를 통해 값을 받아왔지만, 해당 부분을 제거하고 store에서 number state를 가져오도록 변경했다.
이 때, store의 state가 변경될 때마다 input의 value가 변하도록 만들기 위해 subscribe()를 이용한다. subscribe에서 변경된 store의 state로 컴포넌트의 state가 변경되게 setState 함수를 적용한다.

그리고 기존에 상위 컴포넌트에 있던 props를 모두 제거해준다.

그림으로 보면 이렇게 동작하도록 변경되었다!! 훨씬 깔끔해졌다.

⚠️ 그러나 문제가 있다.
이렇게 구현한 컴포넌트(AddNumber)는 우리 어플리케이션에서 사용하는 상태에 의존하고 있기 때문에, 재사용성이 떨어진다.

이 부분을 해결하기 위한 방법은 다음 글에서 정리.

profile
빙글빙글 FE 개발자

0개의 댓글