Skip to content

Instantly share code, notes, and snippets.

@jgautheron
Forked from pesakitan22/CategorySagas.js
Created March 22, 2017 19:07
Show Gist options
  • Save jgautheron/bc07f6515748678a40ed38eab98d816e to your computer and use it in GitHub Desktop.
Save jgautheron/bc07f6515748678a40ed38eab98d816e to your computer and use it in GitHub Desktop.
Redux-Saga for next.js
import {call, put, take, fork} from 'redux-saga/effects'
import {END} from 'redux-saga'
import CategoryActions, {CategoryTypes} from '../Redux/CategoryRedux'
// attempts to fetch category
export function* fetchCategoryServer (api) {
let action = yield take(CategoryTypes.CATEGORY_SERVER)
// check when it stopped
while (action !== END) {
yield fork(fetchCategoryAPI, api)
action = yield take(CategoryTypes.CATEGORY_SERVER)
}
}
function* fetchCategoryAPI (api) {
const response = yield call(api.getCategory)
if (response.ok) {
yield put(CategoryActions.categorySuccess(response.data.data))
} else {
yield put(CategoryActions.categoryFailure())
}
}
import React, {Component} from 'react'
import withRedux from 'next-redux-wrapper'
import {END} from 'redux-saga'
//init Store
import initStore from '../Redux'
//rootSaga & sagaMiddleWare
import rootSaga from '../RootSaga.js'
import { sagaMiddleware } from '../Redux/CreateStore'
//redux actions
import CategoryActions from '../Redux/CategoryRedux'
let clientTask = null
export default function reduxWrapper (ReduxComponent:Object) {
class ReduxContainer extends Component {
static async getInitialProps ({ store, req, isServer }) {
//check if it's on server or not, otherwise you will dispatch everytime you change route
if (isServer) {
const rootTask = sagaMiddleware.run(rootSaga)
//dispatch for fetching initial data
store.dispatch(CategoryActions.categoryServer())
//end the task
store.dispatch(END)
//await for task to complete then display
await rootTask.done.then(() => {
return
})
} else {
return
}
}
constructor (props:any) {
super(props)
//start saga monitor for client side check whether clientTask is running
if (!clientTask) {
clientTask = sagaMiddleware.run(rootSaga)
}
}
render () {
return (
<ReduxComponent {...this.props} />
)
}
}
return withRedux(initStore)(ReduxContainer)
}
import { takeLatest } from 'redux-saga'
import { fork } from 'redux-saga/effects'
// server sagas
import { fetchCategoryServer } from './CategorySagas'
// client sagas
import { login, logout } from './AuthSagas'
// api
import API from '../Services/Api'
/* ------------- API ------------- */
// The API we use is only used from Sagas, so we create it here and pass along
// to the sagas which need it.
const api = API.create()
function* serverSagas () {
yield [
fork(fetchCategoryServer, api)
]
}
function* clientSagas () {
yield [
fork(logout),
fork(login, api)
]
}
export default function* root () {
yield [
fork(serverSagas),
fork(clientSagas)
]
}
@rwieruch
Copy link

Perhaps this article helps other people on how to use Redux Saga in Next. However, thanks for your gist, because it helped me to figure out how things work when the app is server-rendered!

@sephi-dev
Copy link

same here

@JairoLance
Copy link

Gracias por tu aporte.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment