diff --git a/package.json b/package.json index 9a69e8d..983b4a7 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,8 @@ "razzle-dev-utils": "3.0.0-alpha.2", "react-dev-utils": "6.0.4", "react-error-overlay": "5.0.4", + "react-redux": "6.0.1", + "redux": "4.0.1", "resolve-url-loader": "3.0.0", "sass-loader": "7.1.0", "source-map-support": "0.5.9", diff --git a/src/client.js b/src/client.js index fbbe571..4eaa926 100644 --- a/src/client.js +++ b/src/client.js @@ -1,8 +1,24 @@ import React from 'react'; import { hydrate } from 'react-dom'; +import { createStore } from 'redux' +import { Provider } from 'react-redux' + import App from './App'; +import rootReducer from './reducer' + +// Grab the state from a global variable injected into the server-generated HTML +const preloadedState = window.__PRELOADED_STATE__ // eslint-disable-line + +// Allow the passed state to be garbage-collected +delete window.__PRELOADED_STATE__ // eslint-disable-line + +const store = createStore(rootReducer, preloadedState) -hydrate(, document.getElementById('root')); +hydrate( + + + , + document.getElementById('root')); if (module.hot) { module.hot.accept(); diff --git a/src/reducer.js b/src/reducer.js new file mode 100644 index 0000000..08858e0 --- /dev/null +++ b/src/reducer.js @@ -0,0 +1,20 @@ +const initialState = { + counter: 0, +}; + +const reducer = (state = initialState, action) => { + switch (action.type) { + case 'INCREMENT': + return { + counter: state + 1, + }; + case 'DECREMENT': + return { + counter: state - 1, + }; + default: + return state; + } +}; + +export default reducer; diff --git a/src/server.js b/src/server.js index e5f5248..d0ad60c 100644 --- a/src/server.js +++ b/src/server.js @@ -1,25 +1,18 @@ import React from 'react'; import express from 'express'; import { renderToString } from 'react-dom/server'; +import { createStore } from 'redux'; +import { Provider } from 'react-redux'; + import App from './App'; +import rootReducer from './reducer'; const assets = require(process.env.SHINOBI_ASSETS_MANIFEST); -const server = express(); -server - .disable('x-powered-by') - .use(express.static(process.env.SHINOBI_PUBLIC_DIR)) - .get('/*', (req, res) => { - const context = {}; - const markup = renderToString(); - - if (context.url) { - res.redirect(context.url); - } else { - res.status(200).send( - ` +const renderToHtml = (markup, preloadedState) => + ` - + Welcome to Shinobi @@ -34,12 +27,38 @@ server ? `` : `` } - - + + +
${markup}
- -`, - ); + + `; + +const server = express(); +server + .disable('x-powered-by') + .use(express.static(process.env.SHINOBI_PUBLIC_DIR)) + .get('/*', (req, res) => { + const context = {}; + const store = createStore(rootReducer); + const markup = renderToString( + + + , + ); + const preloadedState = store.getState(); + + if (context.url) { + res.redirect(context.url); + } else { + res.status(200).send(renderToHtml(markup, preloadedState)); } }); diff --git a/yarn.lock b/yarn.lock index e3db510..589908b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -673,7 +673,7 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/runtime@^7.1.5": +"@babel/runtime@^7.1.5", "@babel/runtime@^7.3.1": version "7.3.1" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a" integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA== @@ -3387,7 +3387,7 @@ expect@^23.6.0: jest-message-util "^23.4.0" jest-regex-util "^23.3.0" -express@4.16.4: +express@4.16.4, express@^4.16.2: version "4.16.4" resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== @@ -3423,42 +3423,6 @@ express@4.16.4: utils-merge "1.0.1" vary "~1.1.2" -express@^4.16.2: - version "4.16.4" - resolved "https://registry.npmjs.org/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" - integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== - dependencies: - accepts "~1.3.5" - array-flatten "1.1.1" - body-parser "1.18.3" - content-disposition "0.5.2" - content-type "~1.0.4" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.1.1" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.2" - path-to-regexp "0.1.7" - proxy-addr "~2.0.4" - qs "6.5.2" - range-parser "~1.2.0" - safe-buffer "5.1.2" - send "0.16.2" - serve-static "1.13.2" - setprototypeof "1.1.0" - statuses "~1.4.0" - type-is "~1.6.16" - utils-merge "1.0.1" - vary "~1.1.2" - extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -4102,6 +4066,13 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" + integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== + dependencies: + react-is "^16.7.0" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -5575,7 +5546,7 @@ loglevel@^1.4.1: resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7325,6 +7296,15 @@ prop-types@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" +prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -7534,6 +7514,23 @@ react-error-overlay@^5.0.4: resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.2.tgz#888957b884d4b25b083a82ad550f7aad96585394" integrity sha512-7kEBKwU9R8fKnZJBRa5RSIfay4KJwnYvKB6gODGicUmDSAhQJ7Tdnll5S0RLtYrzRfMVXlqYw61rzrSpP4ThLQ== +react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.2: + version "16.8.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.2.tgz#09891d324cad1cb0c1f2d91f70a71a4bee34df0f" + integrity sha512-D+NxhSR2HUCjYky1q1DwpNUD44cDpUXzSmmFyC3ug1bClcU/iDNy0YNn1iwme28fn+NFhpA13IndOd42CrFb+Q== + +react-redux@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-6.0.1.tgz#0d423e2c1cb10ada87293d47e7de7c329623ba4d" + integrity sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ== + dependencies: + "@babel/runtime" "^7.3.1" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.8.2" + react@16.8.2: version "16.8.2" resolved "https://registry.yarnpkg.com/react/-/react-16.8.2.tgz#83064596feaa98d9c2857c4deae1848b542c9c0c" @@ -7623,6 +7620,14 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" +redux@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" + integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -8643,6 +8648,11 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.0" +symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + symbol-tree@^3.2.2: version "3.2.2" resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"