Skip to content

Commit

Permalink
Refactor with redux saga (vercel#13342)
Browse files Browse the repository at this point in the history
Related to [11014](vercel#11014)

Upgraded all the packages from package.json, removed the saga-wrapper package since it is totally outdated to today's use.

I have refactored the whole example using the new API of the next-redux-wrapper package, using their new support of "getStaticProps".

All of the class components were converted to functional, using the new redux hooks API.

If you want me to change anything or you are not satisfied with any given change, I'm open to suggestions.
  • Loading branch information
todortotev authored and rokinsky committed Jul 11, 2020
1 parent 72f8c19 commit 8454438
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 106 deletions.
1 change: 1 addition & 0 deletions examples/with-redux-saga/actions.js
Expand Up @@ -7,6 +7,7 @@ export const actionTypes = {
LOAD_DATA_SUCCESS: 'LOAD_DATA_SUCCESS',
START_CLOCK: 'START_CLOCK',
TICK_CLOCK: 'TICK_CLOCK',
HYDRATE: 'HYDRATE',
}

export function failure(error) {
Expand Down
54 changes: 20 additions & 34 deletions examples/with-redux-saga/components/counter.js
@@ -1,40 +1,26 @@
import { Component } from 'react'
import { connect } from 'react-redux'
import { useSelector, useDispatch } from 'react-redux'

import { increment, decrement, reset } from '../actions'

class Counter extends Component {
increment = () => {
this.props.dispatch(increment())
}
const Counter = () => {
const count = useSelector((state) => state.count)
const dispatch = useDispatch()

decrement = () => {
this.props.dispatch(decrement())
}

reset = () => {
this.props.dispatch(reset())
}

render() {
const { count } = this.props
return (
<div>
<style jsx>{`
div {
padding: 0 0 20px 0;
}
`}</style>
<h1>
Count: <span>{count}</span>
</h1>
<button onClick={this.increment}>+1</button>
<button onClick={this.decrement}>-1</button>
<button onClick={this.reset}>Reset</button>
</div>
)
}
return (
<div>
<style jsx>{`
div {
padding: 0 0 20px 0;
}
`}</style>
<h1>
Count: <span>{count}</span>
</h1>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
<button onClick={() => dispatch(reset())}>Reset</button>
</div>
)
}

const mapStateToProps = ({ count }) => ({ count })
export default connect(mapStateToProps)(Counter)
export default Counter
18 changes: 7 additions & 11 deletions examples/with-redux-saga/components/page.js
@@ -1,18 +1,14 @@
import Link from 'next/link'
import { connect } from 'react-redux'
import { useSelector } from 'react-redux'

import Counter from './counter'
import Clock from './clock'

function Page({
error,
lastUpdate,
light,
linkTo,
NavigateTo,
placeholderData,
title,
}) {
function Page({ linkTo, NavigateTo, title }) {
const placeholderData = useSelector((state) => state.placeholderData)
const error = useSelector((state) => state.error)
const light = useSelector((state) => state.light)
const lastUpdate = useSelector((state) => state.lastUpdate)
return (
<div>
<h1>{title}</h1>
Expand All @@ -33,4 +29,4 @@ function Page({
)
}

export default connect((state) => state)(Page)
export default Page
13 changes: 6 additions & 7 deletions examples/with-redux-saga/package.json
Expand Up @@ -10,13 +10,12 @@
"dependencies": {
"es6-promise": "4.1.1",
"next": "latest",
"next-redux-saga": "4.0.0",
"next-redux-wrapper": "2.0.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-redux": "5.0.7",
"redux": "4.0.1",
"redux-saga": "1.0.1"
"next-redux-wrapper": "6.0.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-redux": "7.2.0",
"redux": "4.0.5",
"redux-saga": "1.1.3"
},
"devDependencies": {
"redux-devtools-extension": "2.13.2"
Expand Down
28 changes: 13 additions & 15 deletions examples/with-redux-saga/pages/_app.js
@@ -1,29 +1,27 @@
import App from 'next/app'
import { Provider } from 'react-redux'
import withRedux from 'next-redux-wrapper'
import withReduxSaga from 'next-redux-saga'

import createStore from '../store'
import { END } from 'redux-saga'
import { wrapper } from '../store'

class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {}
const pageProps = {
...(Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}),
}

if (Component.getInitialProps) {
pageProps = await Component.getInitialProps({ ctx })
if (ctx.req) {
ctx.store.dispatch(END)
await ctx.store.sagaTask.toPromise()
}

return { pageProps }
}

render() {
const { Component, pageProps, store } = this.props
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
const { Component, pageProps } = this.props
return <Component {...pageProps} />
}
}

export default withRedux(createStore)(withReduxSaga(MyApp))
export default wrapper.withRedux(MyApp)
43 changes: 23 additions & 20 deletions examples/with-redux-saga/pages/index.js
@@ -1,28 +1,31 @@
import { Component } from 'react'
import { connect } from 'react-redux'

import { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { END } from 'redux-saga'
import { wrapper } from '../store'
import { loadData, startClock, tickClock } from '../actions'
import Page from '../components/page'

class Index extends Component {
static async getInitialProps(props) {
const { store, isServer } = props.ctx
store.dispatch(tickClock(isServer))

if (!store.getState().placeholderData) {
store.dispatch(loadData())
}
const Index = () => {
const dispatch = useDispatch()

return { isServer }
}
useEffect(() => {
dispatch(startClock())
}, [dispatch])
return (
<>
<Page title="Index Page" linkTo="/other" NavigateTo="Other Page" />
</>
)
}

componentDidMount() {
this.props.dispatch(startClock())
}
export const getStaticProps = wrapper.getStaticProps(async ({ store }) => {
store.dispatch(tickClock(false))

render() {
return <Page title="Index Page" linkTo="/other" NavigateTo="Other Page" />
if (!store.getState().placeholderData) {
store.dispatch(loadData())
store.dispatch(END)
}
}
await store.sagaTask.toPromise()
})

export default connect()(Index)
export default Index
31 changes: 14 additions & 17 deletions examples/with-redux-saga/pages/other.js
@@ -1,23 +1,20 @@
import { Component } from 'react'
import { connect } from 'react-redux'

import { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { wrapper } from '../store'
import { startClock, tickClock } from '../actions'
import Page from '../components/page'

class Other extends Component {
static async getInitialProps(props) {
const { store, isServer } = props.ctx
store.dispatch(tickClock(isServer))
return { isServer }
}

componentDidMount() {
this.props.dispatch(startClock())
}
const Other = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(startClock())
}, [dispatch])

render() {
return <Page title="Other Page" linkTo="/" NavigateTo="Index Page" />
}
return <Page title="Other Page" linkTo="/" NavigateTo="Index Page" />
}

export default connect()(Other)
export const getStaticProps = wrapper.getStaticProps(async ({ store }) => {
store.dispatch(tickClock(false))
})

export default Other
4 changes: 4 additions & 0 deletions examples/with-redux-saga/reducer.js
Expand Up @@ -10,6 +10,10 @@ export const exampleInitialState = {

function reducer(state = exampleInitialState, action) {
switch (action.type) {
case '__NEXT_REDUX_WRAPPER_HYDRATE__': {
return { ...state, ...action.payload }
}

case actionTypes.FAILURE:
return {
...state,
Expand Down
6 changes: 4 additions & 2 deletions examples/with-redux-saga/store.js
@@ -1,5 +1,6 @@
import { applyMiddleware, createStore } from 'redux'
import createSagaMiddleware from 'redux-saga'
import { createWrapper } from 'next-redux-wrapper'

import rootReducer, { exampleInitialState } from './reducer'
import rootSaga from './saga'
Expand All @@ -12,8 +13,9 @@ const bindMiddleware = (middleware) => {
return applyMiddleware(...middleware)
}

function configureStore(initialState = exampleInitialState) {
export const makeStore = (context, initialState = exampleInitialState) => {
const sagaMiddleware = createSagaMiddleware()

const store = createStore(
rootReducer,
initialState,
Expand All @@ -25,4 +27,4 @@ function configureStore(initialState = exampleInitialState) {
return store
}

export default configureStore
export const wrapper = createWrapper(makeStore, { debug: true })

0 comments on commit 8454438

Please sign in to comment.