diff --git a/Hello.js b/Hello.js index 07abf3c..f9a7c16 100644 --- a/Hello.js +++ b/Hello.js @@ -1,21 +1,23 @@ import React from 'react'; -import s from 'Hello.scss'; +import Transmit from 'react-transmit'; import fetch from 'isomorphic-fetch'; +import s from 'Hello.scss'; const Hello = React.createClass({ - getInitialState: function() { - return { - hello: '' - }; - }, - componentDidMount: function() { - fetch('/static/data.json') - .then(r => r.json()) - .then(r => this.setState({hello: r.hello})); - }, render: function() { - return
Hello {this.props.name}. Async hello {this.state.hello}
; + return
Hello {this.props.name}. Async hello {this.props.hello}
; } }); -export default Hello; +export default Transmit.createContainer(Hello, { + // These must be set, or else it would fail to render + initialVariables: {}, + // each fragmen will be resolved into a prop + fragments: { + hello () { + return fetch('http://localhost:3000/static/data.json') + .then(r => r.json()) + .then(r => r.hello); + } + } +}); diff --git a/README.md b/README.md index 23891c3..0caa37b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Follow the tutorial commit-by-commit, to see the server-side rendering drama unf ## Contents (mostly for Google) -### Step 1: minimal Webpack, Babel and React setup +### [Step 1: minimal Webpack, Babel and React setup](https://github.com/dimaip/server-side-rendering/commit/7d1d0677bca0ea94e820dc7e156c89e83ef823bb) RUN: `npm run start` and then open index.html in the browser. @@ -15,7 +15,7 @@ Webpack helps us to bundle our code with dependencies from npm (such as React), and then transforms the code with Babel, to make it compatible with ES5. -### Step 2: trivial server-side rendering with Express +### [Step 2: trivial server-side rendering with Express](https://github.com/dimaip/server-side-rendering/commit/fad6b64e4ec3ee6b378c6ab0abd36f03fdba7c77) RUN: `npm run start` and go to `http://localhost:3000`. @@ -25,7 +25,7 @@ server the client with rendered html, and with webpack we continue to bundle client.js into ES5 code that the browser would understand, just as we did at previous step. -### Step 3: Add styles +### [Step 3: add styles](https://github.com/dimaip/server-side-rendering/commit/53d2ffa7bc9319722addced5bb94c5b231726a1b) Now lets learn to deal with styles. We configure webpack loaders to support loading CSS files. This is cool, but there comes one problem @@ -36,7 +36,7 @@ Let's fix this problem with webpack's ExtractTextPlugin plugin: it extracts all CSS styles into one CSS file that we can serve to our client, so our page will instantly look perfectly styled, even without JS. -### Step 3a: switch to CSS modules +### [Step 3a: switch to CSS modules](https://github.com/dimaip/server-side-rendering/commit/e2c02444b1e7c6ec349511aa9b2da1a52aba5474) Everybody loves CSS modules, and the great news is that they come free with Webpack. The bad news is that we can't use them with server-side rendering, as we don't use @@ -46,7 +46,7 @@ So at this step we broke everything, and the only way to continue from here, is start using Webpack to pre-build code for server-side rendering too, and that's what we'll do at the next step. -### Step 3b: save the day by making webpack to render server-side code +### [Step 3b: save the day by making webpack to render server-side code](https://github.com/dimaip/server-side-rendering/commit/6e36b9690816d414ca36775c6487e0b6dbd8abe3) To save our issue with CSS modules, we make Webpack to render both our client and our server side code. The best way to do it is to @@ -64,7 +64,7 @@ Great! Now our build is fixed, so we can use CSS modules both during client and server rendering. -### Step 4a: asyncronously fetching data +### [Step 4a: asyncronously fetching data](https://github.com/dimaip/server-side-rendering/commit/d9ce281b88d142cf52861223a201de6d47dfd428) Now let's fetch some data asyncronously. We'll use isomorphic-fetch, as it works both on client and server our of the box. @@ -76,7 +76,7 @@ async data when it arrives. Let's try to fix it in the next step. -### Step 4b: use react-transmit to declaratively define data deps +### [Step 4b: use react-transmit to declaratively define data deps](https://github.com/dimaip/server-side-rendering/commit/HEAD) There are multiple ways to solve async rendering issue. Here we'll use react-transmit to declaratively define our data dependencies per component, diff --git a/client.js b/client.js index 7c7ff68..dfd031b 100644 --- a/client.js +++ b/client.js @@ -1,8 +1,9 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import Transmit from 'react-transmit'; import Hello from 'Hello'; -ReactDOM.render( - , +Transmit.render( + Hello, + {name: 'World'}, document.getElementById('app') ); diff --git a/index.html b/index.html index a618045..e565fe3 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,5 @@
- diff --git a/package.json b/package.json index d7c0570..592dad6 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "isomorphic-fetch": "^2.2.1", "path": "^0.12.7", "react": "^0.14.8", - "react-dom": "^0.14.8" + "react-dom": "^0.14.8", + "react-transmit": "^3.1.7" }, "devDependencies": { "babel-cli": "^6.6.5", diff --git a/serverEntry.js b/serverEntry.js index 9f9dd4e..d531798 100644 --- a/serverEntry.js +++ b/serverEntry.js @@ -1,19 +1,22 @@ import fs from 'fs'; import React from 'react'; -import ReactDOMServer from 'react-dom/server'; +import Transmit from 'react-transmit'; import Hello from './Hello.js'; function handleRender(req, res) { - const html = ReactDOMServer.renderToString( - - ); - fs.readFile('./index.html', 'utf8', function (err, file) { - if (err) { - return console.log(err); - } - const document = file.replace(/
<\/div>/, `
${html}
`); - res.send(document); - }); + Transmit.renderToString(Hello, {name: 'World'}) + .then(({reactString, reactData}) => { + fs.readFile('./index.html', 'utf8', function (err, file) { + if (err) { + return console.log(err); + } + const document = file.replace(/
<\/div>/, `
${reactString}
`); + const output = Transmit.injectIntoMarkup(document, reactData, ['/built/client.js']); + res.send(output); + }); + + }) + .catch(e => console.log(e)); } export default handleRender; diff --git a/static/data.json b/static/data.json index b8406d2..86ff58f 100644 --- a/static/data.json +++ b/static/data.json @@ -1,3 +1,3 @@ { - "hello": "world!" + "hello": "WORLD!" }