화면 크기의 정보를 REDUX로 관리하기
2016년 08월 19일
Redux를 활용한 화면 크기 관리
React Component에서 따로따로 resize
이벤트를 거는 것보다 Redux를 통해서 한 군데에서 관리하는 게 낫지 않을까 하는 생각에 Redux를 시작.
2개의 npm module 설치
npm install redux --save
npm install react-redux --save
redux
: Redux 라이브러리react-redux
: React에서 Redux를 좀 더 편하게 사용할 수 있게 해준다.
Redux의 주요 개념
- store: 프로젝트에서 사용하는 모든 동적 데이터를 담아두는 곳
- action: 애플리케이션에서 스토어로 보내는 데이터 묶음
- dispatch: action 객체를 reducer에게 전달
- reducer: action 객체를 받았을 때, 데이터를 어떻게 바꿀지 처리할지 정의하는 객체
상태 변경 순서
- 상태를 변경하려면
dispatch
로 action 객체를 보낸다. reducer
는 action 객체를 받아서 상태를 변경한다.- 상태를 props로 전달받을 수 있다.
Action과 Reducer에서 사용할 상수
/redux/constants.jsx
export const RESIZE = "RESIZE"; // 화면 리사이즈
Action
애플리케이션에서 스토어로 보내는 데이터 묶음.
store.dispatch()
를 통해 보낼 수 있다. React-Redux에서는 this.props.dispatch()
를 사용할 수 있다.
/redux/actions/resize.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은 지정한 객체의 모든 속성을 대상 객체로 병합한다.
return Object.assign({}, state, {
screenWidth: action.screenWidth,
screenHeight: action.screenHeight,
});
}
return state;
};
const rootReducer = combineReducers({
size,
});
export default rootReducer;
Store 생성
Routes.jsx
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 (
<Provider store={store}>
<ReduxTest />
</Provider>
);
}
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 (
<div>
<p>screenWidth: {this.props.size.screenWidth}</p>
<p>screenHeight: {this.props.size.screenHeight}</p>
</div>
);
},
});
// store의 state를 컴포넌트의 props에 매핑 시켜준다.
// component의 props에 size 속성을 추가할 수 있다.
let mapStateToProps = (state) => {
return {
size: state.size,
};
};
ReduxTest = connect(mapStateToProps)(ReduxTest);
// 컴포넌트의 props에는 dispatch와 size가 추가되어 있다.
export default ReduxTest;