React-Redux

yoosg·2020년 1월 26일
0

React-Redux에서 제공하는 기능을 활용하여 Counter 예제를 만들어 보면서 전역 상태관리의 흐름을 이해하자.

1. Provider

provider는 react-redux에서 제공하는 컴포넌트로 이를 통해 store에 접근 가능하게 만들어준다.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

// redux store
import {Provider} from 'react-redux'
import {createStore} from 'redux';
import rootReducer from './modules';
import {composeWithDevTools} from 'redux-devtools-extension'

const store = createStore(rootReducer, composeWithDevTools());

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>, document.getElementById('root')
);

위처럼 Provider로 App 컴포넌트를 감싸주면 App컴포넌트 내부에 존재하는 각각의 컴포넌트에서 store에 접근할 수 있게된다.

2. connect

connect 함수 또한 react-redux에서 제공하는 기능으로 상태 변화가 필요한 각각의 하위 컴포넌트와 store를 연결해주는 함수다.

mapStateToProps

connect함수의 첫번째 인자로 들어가는 값으로 store에서 state값을 props로 가져와 사용할 수 있다. 컴포넌트 내에서 store의 값을 가져올 필요가 없다면 null로 대신하면 된다.

import React from 'react'

// Set Redux
import {connect} from "react-redux"
import {setDiff, increase, decrease} from '../../modules/counter'

const CounterConnect = ({number, diff}) => {
 
  return (
    <div>
      <h1>{number}</h1>
      <input type="number" value={diff} onChange={onChange}/>
    </div>
  )
}
const mapStateToProps = state => {
  return {
    diff: state.counter.diff,
    number: state.counter.number
  }
}

export default connect(mapStateToProps, null)(CounterConnect) 

mapDispatchProps

connect함수의 두번째 인자로 store의 상태를 바꾸기 위해 dispatch를 사용 가능하게 만들어준다.

import React from 'react'

// Set Redux
import {connect} from "react-redux"
import {setDiff, increase, decrease} from '../../modules/counter'

const CounterConnect = ({setDiff, increase, decrease, number, diff}) => {
  
  const onChange = e => {
    setDiff(parseInt(e.target.value)); 
  }
  return (
    <div>
      <h1>{number}</h1>
      <input type="number" value={diff} onChange={onChange}/>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  )
}
const mapStateToProps = state => {
  return {
    diff: state.counter.diff,
    number: state.counter.number
  }
}
const mapDispatchToProps = (dispatch) => ({
  increase: () => dispatch(increase()),
  decrease: () => dispatch(decrease()),
  setDiff:  diff => dispatch(setDiff(diff))
  })

export default connect(mapStateToProps, mapDispatchToProps)(CounterConnect) 

mapDispatchToProps없이 이렇게도 표현 가능하다.

import React from 'react'

// Set Redux
import {connect} from "react-redux"
import {setDiff, increase, decrease} from '../../modules/counter'

const CounterConnect = ({setDiff, increase, decrease, number, diff}) => {
  
  const onChange = e => {
    setDiff(parseInt(e.target.value)); 
  }
  return (
    <div>
      <h1>{number}</h1>
      <input type="number" value={diff} onChange={onChange}/>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  )
}
const mapStateToProps = state => {
  return {
    diff: state.counter.diff,
    number: state.counter.number
  }
}

export default connect(mapStateToProps, { increase, decrease, setDiff })(CounterConnect) 

0개의 댓글