화면 크기의 정보를 REDUX로 관리하기
React Component에서 따로따로 resize 이벤트를 거는 것보다 Redux를 통해서 한 군데에서 관리하는게 낫지 않을까 하는 생각에 Redux를 시작.
2개의 npm module 설치
npm install redux --save npm install react-redux --save ( React에서 redux를 좀 더 편하게 사용할 수 있게 해준다 )
의미
- store : 프로젝트에서 사용하는 모든 동적 데이터들을 담아두는 곳 입니다.
- action : 애플리케이션에서 스토어로 보내는 데이터 묶음입니다.
- dispatch : action객체를 reducer에게 전달
- reducer : action 객체를 받았을 때, 데이터를 어떻게 바꿀지 처리할지 정의하는 객체입니다.
상태 변경 순서
1. 상태를 변경하려면 dispatch로 action 객체를 보낸다.
2. reducer는 action객체를 받아서 상태를 변경
3. 상태를 props를 전달 받을 수 있다.
action과 reducer에서 사용할 상수
/redux/constants.jsx
export const RESIZE = 'RESIZE'; // 화면 리사이즈
action
애플리케이션에서 스토어로 보내는 데이터 묶음.
store.dispatch()를 통해 보낼 수 있다. react-redux에서는 this.props.dispatch()를 사용할 수 있다.
/redux/constants.jsx
import { RESIZE } from '../constants'; export function resize( screenWidth, screenHeight ) { return { type : RESIZE, // 필수로 들어가는 부분, 어떤 액션인지 구분 screenWidth : screenWidth, screenHeight : screenHeight } }
reducer
애플리케이션의 상태가 어떻게 바뀌는지 지정.
/redux/reducers/root.jsx
import { RESIZE } from '../constants'; import { combineReducers } from 'redux'; // state의 초기상태 정의 const size = ( state = { screenWidth : 0, screenHeight : 0 }, action ) => { if ( action.type === RESIZE ) { // Object.assign은 지정한 객체의 모든 속성을 대상 객체로 병합한다. // 하나 이상의 소스 개체에서 대상 개체로 값을 복사합니다. ( https://msdn.microsoft.com/ko-kr/library/dn858229(v=vs.94).aspx ) return Object.assign( {}, state, { screenWidth : action.screenWidth, screenHeight : action.screenHeight }); } return state; }; const rootReducer = combineReducers({ size }); export default rootReducer;
Store 생성
Routes.jsx
Routes에 적용 import ReduxTest from './components/ReduxTest.jsx'; // redux 사용할 컴포넌트 import { createStore } from 'redux'; // 스토어 생성하기 위해 import rootReducer from './redux/reducers/root' // 작성한 reducer import { Provider } from 'react-redux'; // Provider에 store를 설정해주면 하위 컴포넌트들에 parent-child 구조로 전달해주지않아도 connect 될 때 store에 접근할 수 있게 해준다. const store = createStore( rootReducer ); // 스토어 생성 render(){ return () }
Component에서 Redux 사용하기
/components/ReduxTest.jsx
import { resize } from '../../redux/actions/resize' // dispatch로 넘길 action객체 불러오기 import { connect } from 'react-redux'; // connect는 Component를 Store에 연결해준다. var ReduxTest = React.createClass({ componentDidMount() { window.addEventListener( 'resize', this.resize ); }, componentWillUnmount() { window.removeEventListener( 'resize', this.resize ); }, resize() { // resize 될 때 마다 dispatch로 action객체를 전달 this.props.dispatch( resize( window.innerWidth, window.innerHeight) ); }, render(){ return() } }); // store 의 state 를 컴포넌트의 props 에 매핑 시켜준다. // component의 props에 size 속성을 추가할 수 있다. let mapStateToProps = ( state ) => { return { size : state.size } }; ReduxTest = connect( mapStateToProps )( ReduxTest ); // 컴포넌트의 props에는 dispatch와 size가 추가되어 있다. export default ReduxTest ;screenWidth : { this.props.size.screenWidth }
screenHeight : { this.props.size.screenHeight }