본문 바로가기
Tech/React

Next + Typscript + Redux + Redux-Saga 설정

by Dog발자. 2021. 3. 11.
반응형

 

React + Redux 상테에서 Redux-Saga 설정

 

1. redux-saga 모듈 설치

npm install redux-saga
npm install axios // saga 로직에서 쓰임

2. actions, reducers, store 폴더에 해당 파일을 생성한다.

store/actions/actionTypes.ts 수정

export const INCREASE = 'counter/INCREASE'
export const DECREASE = 'counter/DECREASE'
// search
export const SEARCH = 'SEARCH';
export const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
export const SEARCH_FAIL = 'SEARCH_FAIL';

store/actions/search.ts 추가

import {SEARCH , SEARCH_SUCCESS, SEARCH_FAIL  } from './actionTypes';

export const search = (payload) => {
    return {
        type: SEARCH,
        payload: payload
    }
}

export const searchSuccess = (data) => {
    return {
        type: SEARCH_SUCCESS,
        data: data
    }
}

export const searchFail = (error) => {
    return {
        type: SEARCH_FAIL,
        error: error
    }
}

store/reducers/search.ts 추가

import * as actions from 'store/actions/actionTypes'

const initialState = {
    data: [],
    payload: {},
    error: ''
}

export default (state=initialState, action) => {
    switch(action.type){
      case actions.SEARCH:
        console.log(1, {
          ...state,
          payload: action.payload
        })
        return {
          ...state,
          payload: action.payload
        }
      case actions.SEARCH_SUCCESS:
        console.log(2, {
          ...state,
          data: action.data
        })
        return {
          ...state,
          data: action.data
        }
      case actions.SEARCH_FAIL:
        console.log(3, {
          ...state,
          error: action.error
        })
        return {
          ...state,
          error: action.error
        }
      default:
        return state;
    }
  }

store/reducers/index.ts 수정

import { combineReducers } from "redux";
import counter from "./counter";
import search from "./search";

const rootReducer = combineReducers({
    counter: counter,
    search: search
})

export default rootReducer

export type RootState = ReturnType<typeof rootReducer>

store/sagas/SearchSaga.ts 추가

import { call, put, takeEvery } from "redux-saga/effects";
import {SEARCH} from 'store/actions/actionTypes'
import * as actions from "store/actions/search";
import axios from "axios";
 
function searchAPI(data) {
    return axios.get(`https://api.tvmaze.com/search/shows?q=superman`)
}

function* fetchSearchSaga(action) {
    try {
        const { data } = yield call(searchAPI, action.data)
        yield put(actions.searchSuccess(data));
    } catch (error) {
        yield put(actions.searchFail('error'));
    }
}

/**
 * SEARCH DISPATH EVENT WATCH
 * 이벤트기 감지되었을때 동작한다.
 */
export default function* watchSearch() {
    yield takeEvery(SEARCH, fetchSearchSaga);
}

store/sagas/index.ts 추가

import { all, call } from 'redux-saga/effects';
import watchSearch from './SearchSaga'
 
export default function* rootSaga() {
  yield all([
      call(watchSearch)
  ])
}

 

store/index.ts 파일을 수정합니다.

import { createStore, applyMiddleware, Middleware, StoreEnhancer } from "redux"
import rootReducer from "./reducers";
import { MakeStore, createWrapper } from "next-redux-wrapper";
import createSagaMiddleware from "redux-saga";
import rootSaga from "./sagas";

const bindMiddleware = (middleware: Middleware[]): StoreEnhancer => {
    if (process.env.NODE_ENV !== 'production') {
        const { composeWithDevTools } = require('redux-devtools-extension');
        return composeWithDevTools(applyMiddleware(...middleware));
    }
    return applyMiddleware(...middleware);
}

const makeStore: MakeStore<{}> = () => {
    const sagaMiddleware = createSagaMiddleware();
    const middlewares = [sagaMiddleware];

    const store = createStore(rootReducer, {}, bindMiddleware([...middlewares]));
    sagaMiddleware.run(rootSaga);
    return store
}
    

export const wrapper = createWrapper<{}>(makeStore, { debug: true });

3. Redux-Saga 정상동작확인

npm run dev

실행 후 웹페이지에 접속했을때 VScode 터미널에 아래 내용이 나오면 정상적으로 설정된것입니다.

4. Redux-Saga 테스트

 

pages/index.tsx 파일을 수정합니다.

import Head from 'next/head'

import { useCallback } from 'react'
import { useDispatch, useSelector } from 'react-redux';
import {RootState} from 'store/reducers'
import { countUp, countDown } from 'store/actions/count';
import { search } from 'store/actions/search';


import styles from 'styles/Home.module.css'
import styled from 'styled-components';

const NavbarWrapper = styled.div`
  background-color: #ededed;
  padding: ${({ theme }) => theme.colors.black}
`

export default function Home() {
  const dispatch = useDispatch();
  const {value} = useSelector((state: RootState) => state.counter)
  const searchData = useSelector((state: RootState) => state.search)

  const upEvent = useCallback(() => {
    dispatch(countUp())
  }, [])

  const downEvent = useCallback(() => {
    dispatch(countDown())
  }, [])

  const searchEvent = useCallback(() => {
    dispatch(search({test: 'test1'})) 
    //'superman'
  }, [])

  return (
    <NavbarWrapper>
        <Head>
          <title>Create Next App</title>
          <link rel="icon" href="/favicon.ico" />
        </Head>
        <div className={styles.home}>
          <div className={styles['counter__text']}>{value}</div>
          <div className={styles['button__area']}>
            <button onClick={upEvent}>Up</button>
            <button onClick={downEvent}>Down</button>
          </div>
          <button onClick={searchEvent}>Search</button>
        </div>
        {searchData.data && (
        <div>
          {searchData.data.map((show, index) => (
            <div key={index}>
              <a href={show.url}>{show.name}</a>
              <div>점수 : {show.score}</div>
              <div>타입 : {show.type}</div>
              <div>언어 : {show.language}</div>
            </div>
          ))}
        </div>
      )}
    </NavbarWrapper>
  )
}

전체적인 코드는 제 Github 공유드리겠습니다. github.com/jkkim09/nextjs-study

 

jkkim09/nextjs-study

Contribute to jkkim09/nextjs-study development by creating an account on GitHub.

github.com

아래 링크들을 하나씩 따라시면 Redux-Saga 설정까지 해보실 수 있습니다.

 

jktech.tistory.com/44

 

Next.js(react) 프로젝트 시작

React의 SSR (server-side rendering) 프레임워크인 Next 프로젝트 환경: Windows, VScode, npm ※ npx는 자바스크립트 패키지 관리 모듈인 npm(Node Package Module)의 npm@5.2.0 버전부터 새로 추가된 도구입..

jktech.tistory.com

 

jktech.tistory.com/45

 

Next + Typescript 설정

Next 프로젝트 설정은 제 블로그 에서 확인할 수 있습니다. jktech.tistory.com/44 Next.js(react) 프로젝트 시작 React의 SSR (server-side rendering) 프레임워크인 Next 프로젝트 환경: Windows, VScode, npm..

jktech.tistory.com

jktech.tistory.com/46

 

Next + Typscript + Redux 설정

Redux를 설정전 Next, Typescript 설정은 저의 다른 글에서 확인할 수 있습니다. jktech.tistory.com/44 Next.js(react) 프로젝트 시작 React의 SSR (server-side rendering) 프레임워크인 Next 프로젝트 환경: Wi..

jktech.tistory.com

 

반응형

'Tech > React' 카테고리의 다른 글

Next + Typscript + Redux 설정  (0) 2021.03.11
Next + Typescript 설정  (0) 2021.03.11
Next.js(react) 프로젝트 시작  (0) 2021.03.11

댓글