Why does saga not execute on the server side, but saga runs normally on the client side?
See original GitHub issueDescribe the bug
Why does saga not execute on the server side, but saga runs normally on the client side?
The strange thing is that in my local development environment, when I run npm run dev
for the first time, the saga does not work, but when I modify the jsx file and hot load it, the server-side saga works
But when I package it in the production environment, the server-side saga doesn’t work
_app.jsx
import { enquireScreen } from 'enquire-js'
import App from 'next/app'
import { withRouter } from 'next/router'
import React from 'react'
import { setRem } from 'lib/rem'
import './style.scss'
import 'css/index.less'
import { DefaultSeo } from 'next-seo'
import SEO from '../../next-seo.config'
import '@/utils/router-event'
import { appWithTranslation } from 'lib/i18n'
import { authCheck } from '@/lib/auth'
import { initNextServer } from '@/lib/next-server'
import { notification } from 'antd'
import { isClient } from '@/utils/helper'
import { userKey, tokenKey } from '@/lib/token'
import { directLogout } from '@/lib/auth'
import wrapper from '../redux/store'
import { END } from 'redux-saga'
import { authLogoutSuccess } from '@/redux/modules/auth/actions'
import {
authLoginSuccess,
authUserInfoSuccess,
authUserInfoRequest,
} from '@/redux/modules/auth/actions'
// @withReduxStore
class NextApp extends App {
constructor(props) {
super(props)
this.state = {
userAgent: {
userAgent: 'pc',
},
isMobile: false,
}
}
static getInitialProps = wrapper.getInitialAppProps(
(store) => async ({ Component, ctx }) => {
let pageProps = {}
store.dispatch(authUserInfoRequest()) // <------------
if (Component.getInitialProps) {
try {
pageProps = await Component.getInitialProps({
...ctx,
store,
})
} catch (e) {
const statusCode = e?.response?.status
if (!isClient() && statusCode === 401) {
store.dispatch(authLogoutSuccess())
ctx.res.clearCookie(userKey)
ctx.res.clearCookie(tokenKey)
ctx.res.writeHead(301, { Location: '/' })
ctx.res.end()
}
}
}
if (ctx.req) {
console.log('Saga is executing on server, we will wait')
store.dispatch(END)
await store.sagaTask.toPromise()
console.log('Saga is executing on server, done')
}
return { pageProps }
}
)
render() {
const { Component, pageProps } = this.props
return (
<>
<DefaultSeo {...SEO} />
<Component {...pageProps} />
</>
)
}
}
export default appWithTranslation(withRouter(wrapper.withRedux(NextApp)))
store.js
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import { createWrapper, HYDRATE } from 'next-redux-wrapper'
import rootReducer from './reducers'
import rootSaga from './sagas'
const bindMiddleware = (middleware) => {
if (process.env.NODE_ENV !== 'production') {
const { composeWithDevTools } = require('redux-devtools-extension')
return composeWithDevTools(applyMiddleware(...middleware))
}
return applyMiddleware(...middleware)
}
export const makeStore = () => {
const sagaMiddleware = createSagaMiddleware()
const store = createStore(rootReducer, bindMiddleware([sagaMiddleware]))
store.sagaTask = sagaMiddleware.run(rootSaga)
// Hot reload reducers (requires Webpack or Browserify HMR to be enabled)
if (process.env.NODE_ENV !== 'production' && module.hot) {
module.hot.accept('./reducers', () =>
// eslint-disable-next-line global-require
store.replaceReducer(require('./reducers').default)
)
}
return store
}
export default createWrapper(makeStore, { debug: false })
saga.js
import {
all,
fork,
put,
takeLatest,
takeEvery,
call,
take,
} from 'redux-saga/effects'
import AuthProvider from '@/api/auth'
import { setToken, removeToken, removeUserInfo, setUserInfo } from '@/lib/token'
import {
authLoginSuccess,
actionTypes,
authUserInfoSuccess,
authLogoutSuccess,
authUserInfoRequest,
} from './actions'
function* authLogin({ payload }) {
const { email, password } = payload
try {
const { data } = yield call(AuthProvider.login, {
email: email.trim(),
password,
})
if (data.access_token) {
setToken(data.access_token)
yield put(authLoginSuccess(data.access_token))
yield put(authUserInfoRequest())
}
} catch (e) {
console.log('saga authLogin', e)
yield put(authLoginSuccess(null))
removeToken()
}
}
function* getUserInfo() {
while (true) {
yield take(actionTypes.AUTH_GET_USER_INFO_REQUEST)
try {
const userInfo = yield call(AuthProvider.getUserInfo, {
include: [],
})
console.log('saga getUserInfo', userInfo)
yield put(authUserInfoSuccess(userInfo))
} catch (e) {
yield put(authUserInfoSuccess({}))
removeUserInfo()
}
}
}
function* logout({ payload }) {
try {
yield call(AuthProvider.logout)
removeToken()
removeUserInfo()
yield put(authLogoutSuccess())
} catch (e) {}
}
export default [
takeLatest(actionTypes.AUTH_LOGIN_REQUEST, authLogin),
fork(getUserInfo),
takeLatest(actionTypes.AUTH_LOGOUT_REQUEST, logout),
// ...
]
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (2 by maintainers)
Top Results From Across the Web
Why does saga not execute on the server side, but ... - GitHub
Describe the bug Why does saga not execute on the server side, but saga runs normally on the client side? The strange thing...
Read more >React redux-saga on server side doesn't take action after ...
I have some problems with my universal react app runing with saga. I'm rendering react on server. One of my react component executes...
Read more >Server Rendering - Redux - JS.ORG
Because the client side executes ongoing code, it can start with an empty initial state and obtain any necessary state on demand and...
Read more >Pattern: Saga - Microservice Architecture
A client that initiates the saga, which an asynchronous flow, using a synchronous request (e.g. HTTP POST /orders ) needs to be able...
Read more >How I spent my Christmas enabling SSR | by Craig Taub
The idea is that the user should have a first-class experience anywhere, and that includes on a mobile device or a bad internet...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
It doesn’t seem to be working, here’s an example of when first launching it using the page for access. It does not execute the asynchronous function inside saga
https://codesandbox.io/s/jovial-night-mtkbt?file=/pages/index.js
Because the console.log of the asynchronous function is not printed
I hope you can help me to answer my questions, thank you very much!
@kirill-konshin