Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 노드
- Redux
- 영화
- 리액트
- web
- 영화리뷰
- 개발자
- 클로즈가드
- git
- 주짓떼로
- 주짓수
- 파이썬
- 프로그래밍
- 자바스크립트
- 영화감상
- 디자인패턴
- 주짓떼라
- nodejs
- 드릴
- graphQL
- 웹개발
- 솔로드릴
- JavaScript
- 엄티로드
- REACT
- 개발
- Express
- development
- Node
- 하프가드
Archives
- Today
- Total
As i wish
[React] Redux-saga 적용하기 본문
React 프로젝트를 하다 보면 자연스럽게 Redux 에 대하여 접하게 되고 그 외의 비동기 통신, 액션 컨트롤 등 다양한 것을 하기 위해 (대부분 비동기 통신) Redux-thunk, Redux-saga 를 접하게 됩니다.
이번 포스팅에서는 그런 Redux-saga 를 React 에 적용하는 법을 써보겠습니다.
일단 먼저 store 를 만듭니다.
store.js
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware()
import reducers from './reducers';
const create = () => {
const store = createStore(
reducers,
applyMiddleware(sagaMiddleware));
sagaMiddleware.run(rootSaga);
return store;
}
export default create;
sagas.js
import { all, put, call, takeEvery, delay } from 'redux-saga/effects'
// worker Saga: 비동기 증가 태스크를 수행할겁니다.
function* showPopup() {
yield delay(2000);
yield put({ type: 'SET_POPUP', payload: {text:'Test'}})
// yield put({ type: 'HIDE_POPUP' })
}
// watcher Saga: 각각의 INCREMENT_ASYNC 에 incrementAsync 태스크를 생성할겁니다.
function* watchIncrementAsync() {
yield takeEvery('SHOW_POPUP', showPopup)
}
export default function* rootSaga() {
yield all([
watchIncrementAsync(),
]);
}
그 다음 root 에다가 store 를 만든 뒤 Provider 에 props로 넣어줍니다.
client.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import create from './store';
import { hot } from 'react-hot-loader/root';
import Popup from './components/Popups'; // Class 사용
const Store = create();
const Hot = hot(Popup);
ReactDOM.render(
<Provider store={Store}>
<Hot />
</Provider>,
document.getElementById('root')
); // Class 사용
사실 보시면 알겠지만 Redux-saga 는 미들웨어이기 때문에 실제 Reducer를 붙여주는것과 동일하지만 중간에 한코드만 넣어주면 됩니다.
store.js 에서 applyMiddleware, constsagaMiddleware=createSagaMiddleware() 이것들이 바로 그것이죠!
기존 미들웨어 없이는 다음과 같이 store.js 를 구성해주면 됩니다. (redux-saga 없이 적용)
import { createStore } from 'redux'
import reducers from './reducers';
const create = () => {
const store = createStore(reducer);
return store;
}
export default create;
reducer.js
import * as actions from './actions';
const initialState = {
text: ''
}
const reducer = (state=initialState, action) => {
const { type, payload } = action;
switch (type) {
case actions.SET_POPUP:
return {
...state,
text: payload.text
}
case actions.HIDE_POPUP:
return {
...state,
text: ''
};
default:
return state;
}
};
export default reducer;
* 참고로 SSR 를 위해 next.js 에서 redux, redux-saga 를 사용하기 위해서는 몇가지 더 추가해야할 사항이 있습니다.
import React from 'react';
import Head from 'next/head';
import PropTypes from 'prop-types';
import withRedux from 'next-redux-wrapper'; // With redux in next
import withReduxSaga from 'next-redux-saga'; // With redux-saga in next
import { applyMiddleware, compose, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { Provider } from 'react-redux';
import reducers from '../reducers';
import rootSaga from '../sagas';
import AppLayout from '../components/AppLayout';
const NodeBird = ({ Component, store, pageProps }) =>
// Using Provider link react with redux
(
<Provider store={store}>
<Head>
<title>NodeBird</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.20.5/antd.css" />
<link rel="stylesheet" type="text/css" charSet="UTF-8" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" />
</Head>
<AppLayout>
<Component {...pageProps} />
</AppLayout>
</Provider>
);
NodeBird.propTypes = {
Component: PropTypes.elementType.isRequired,
store: PropTypes.object.isRequired,
pageProps: PropTypes.object.isRequired,
};
NodeBird.getInitialProps = async (context) => {
console.log(context);
const { ctx, Component } = context;
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
};
const configureStore = (initialState, options) => {
const sagaMiddleware = createSagaMiddleware();
const middlewares = [sagaMiddleware];
const enhancer = compose(applyMiddleware(...middlewares));
const store = createStore(reducers, initialState, enhancer);
store.sagaTask = sagaMiddleware.run(rootSaga);
return store;
};
export default withRedux(configureStore)(withReduxSaga(NodeBird));
next.js 사용했을 때 다음과 같이 configureStore 에서 해줘야 각각의 page 내의 getInitailProps에서 redux 및 redux-saga 를 사용할 수 있습니다.
'React JS' 카테고리의 다른 글
React + Next + Express + Node js -> aws ec2 를 이용한 배포 - 1 (0) | 2019.12.20 |
---|---|
[React] children 컴포넌트에 props 전달하기 (0) | 2019.12.10 |
[React SNS] React SNS 만들기 - 5 (BackEnd server - Web server 만들기) (0) | 2019.08.13 |
[React SNS] React SNS 만들기 - 4 - 2 (redux saga 적용) (0) | 2019.08.12 |
[React SNS] React SNS 만들기 - 4 - 1 (redux saga 란, airbnbStyle applied) (0) | 2019.08.12 |
Comments