본문 바로가기
javascript

react-redux 사용법

by 초특급하품 2020. 5. 17.

부모-자식으로 이루어진 복잡한 컴포넌트들 사이에 이벤트를 주고받는 과정을 구현한다고 생각해보자.

props의 callback으로 자식은 부모 컴포넌트에게 이벤트를 전달하고, 부모는 다른 자식에게 state 변경을 통해 이벤트를 전달한다. 어떤 상태 값과 관련이 있는 컴포넌트만 신경을 쓰면 좋겠지만 그 둘을 연결하는 모든 컴포넌트를 거쳐야 한다. 성능을 떠나서 반복적인 작업에 골치가 아프다.

 

 

redux

redux는 컴포넌트 전역에서 관리할 저장소를 만든다. 컴포넌트 간에 이벤트 전달을 위한 코드를 추가할 필요가 없다.

export default reducer(function(state = { count: 0 }, action) {
  switch(action.type) {
    case 'INCREMENT':
      return {
        ...state,
        count: state.count + action.diff
      }
    case 'DECREMENT':
      return {
        ...state,
        count: state.count - action.diff
      }
    default:
      return state
  }
})

 

각 컴포넌트에서는 이 저장소를 통해 상태를 변경하고, 변경을 감지한다. 이를 react에서 구현한 react-redux를 사용한다.

 

 

react-redux

connect

저장소와 연결시키기 위해 컴포넌트를 connect 함수로 wrapping 해야 한다. 주로 containers 구조를 만들어서 작업하는 것 같다.

connectmapStateToPropsmapDispatchToProps 두 함수를 인자로 받아 함수를 리턴한다. 리턴된 함수는 다시 컴포넌트를 인자로 받아서 완성된 wrapping 컴포넌트를 리턴한다.

 

mapStateToProps는 redux 저장소에 있는 상태가 변경되었을 때 react에게 알려준다. 그래서 인자로 state를 제공한다.

import { connect } from 'react-redux'

...

export default connect((state) => ({ count: state.count }))(Component)

아래 나올 combineReducers로 묶은 경우에는 state.{reduer}.*로 store에 접근해야 한다.

 

 

mapDispatchToProps는 redux 저장소에 이벤트를 발생시킬 때 사용한다. 인자로 dispatch를 받아 정의한 액션을 넘긴다.

import { connect } from 'react-redux'

...

export default connect(
  null,
  (dispatch) => ({ increase: (diff) => dispatch({ type: 'INCREMENT', diff }) }),
)(Component)

 

provider

리덕스를 적용시키기 위해 최상위 컴포넌트를 감싸는 provider를 추가한다. 여기에 위에서 작업한 저장소를 넣어준다.

보통 store를 counter 뿐만 아니라 여러 개를 사용하기 때문에 combineReducers를 사용해서 하나로 묶은 과정을 거친다.

import { combineReducers } from 'redux'
import counter from './counter'

export default combineReducers({
    counter,
})

 

import { createStore } from 'redux';
import { Provider } from 'react-redux'
import combineReducers from './store/modules'

...

const store = createStore(combineReducers);

export default App = () => {
  return (
    <Provider store={store}>
      <View>
        <Component/> {/* container 컴포넌트 */}
      </View>
    </Provider>
  )
}

 

'javascript' 카테고리의 다른 글

React class vs function component 차이점  (0) 2020.05.17
Typescript 타입 정의 파일  (0) 2020.03.29
CommonJS / ES 모듈 로딩 방식  (1) 2020.03.29
ES8의 async와 await  (0) 2019.10.16
ES6의 Promise  (0) 2019.10.16

댓글