diff --git a/examples/with-redux-saga/actions.js b/examples/with-redux-saga/actions.js index b7edc5240eb33..8e168150db208 100644 --- a/examples/with-redux-saga/actions.js +++ b/examples/with-redux-saga/actions.js @@ -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) { diff --git a/examples/with-redux-saga/components/counter.js b/examples/with-redux-saga/components/counter.js index ead3739277d9a..114077e28dc8a 100644 --- a/examples/with-redux-saga/components/counter.js +++ b/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 ( -
- -

- Count: {count} -

- - - -
- ) - } + return ( +
+ +

+ Count: {count} +

+ + + +
+ ) } -const mapStateToProps = ({ count }) => ({ count }) -export default connect(mapStateToProps)(Counter) +export default Counter diff --git a/examples/with-redux-saga/components/page.js b/examples/with-redux-saga/components/page.js index bcc5f3bb6b4b9..72cb187723abe 100644 --- a/examples/with-redux-saga/components/page.js +++ b/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 (

{title}

@@ -33,4 +29,4 @@ function Page({ ) } -export default connect((state) => state)(Page) +export default Page diff --git a/examples/with-redux-saga/package.json b/examples/with-redux-saga/package.json index 112871ce7ff98..112162b3ca244 100644 --- a/examples/with-redux-saga/package.json +++ b/examples/with-redux-saga/package.json @@ -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" diff --git a/examples/with-redux-saga/pages/_app.js b/examples/with-redux-saga/pages/_app.js index 130e85fe05ca3..356e395f87997 100644 --- a/examples/with-redux-saga/pages/_app.js +++ b/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 ( - - - - ) + const { Component, pageProps } = this.props + return } } -export default withRedux(createStore)(withReduxSaga(MyApp)) +export default wrapper.withRedux(MyApp) diff --git a/examples/with-redux-saga/pages/index.js b/examples/with-redux-saga/pages/index.js index 8464903ca6cfc..135170df5ef84 100644 --- a/examples/with-redux-saga/pages/index.js +++ b/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 ( + <> + + + ) +} - componentDidMount() { - this.props.dispatch(startClock()) - } +export const getStaticProps = wrapper.getStaticProps(async ({ store }) => { + store.dispatch(tickClock(false)) - render() { - return + if (!store.getState().placeholderData) { + store.dispatch(loadData()) + store.dispatch(END) } -} + await store.sagaTask.toPromise() +}) -export default connect()(Index) +export default Index diff --git a/examples/with-redux-saga/pages/other.js b/examples/with-redux-saga/pages/other.js index 17ad54be40fb8..db5176a1690da 100644 --- a/examples/with-redux-saga/pages/other.js +++ b/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 - } + return } -export default connect()(Other) +export const getStaticProps = wrapper.getStaticProps(async ({ store }) => { + store.dispatch(tickClock(false)) +}) + +export default Other diff --git a/examples/with-redux-saga/reducer.js b/examples/with-redux-saga/reducer.js index 57418e73ce1a2..bdfd6329f688c 100644 --- a/examples/with-redux-saga/reducer.js +++ b/examples/with-redux-saga/reducer.js @@ -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, diff --git a/examples/with-redux-saga/store.js b/examples/with-redux-saga/store.js index 4ac635321ab5e..c440320f15cc5 100644 --- a/examples/with-redux-saga/store.js +++ b/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' @@ -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, @@ -25,4 +27,4 @@ function configureStore(initialState = exampleInitialState) { return store } -export default configureStore +export const wrapper = createWrapper(makeStore, { debug: true })