goatslacker / alt

Isomorphic flux implementation
http://alt.js.org/
3.45k stars 323 forks source link

Server rendering with react-router 1.0.0 #601

Closed syarul closed 8 years ago

syarul commented 8 years ago

Manage to do the server side rendering react-router v1.0.0 how do I pick this up on client?

app.use((req, res) => {

  alt.bootstrap(JSON.stringify(res.locals.data || {}))
  const location = createLocation(req.url);
  match({ routes, location }, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message)
    } else if (redirectLocation) {
      res.status(302).send(redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
      const markup = React.renderToString(<RoutingContext {...renderProps}/>);
      const isoWrappedMarkup = Iso.render(markup, alt.flush());
      res.render('layout', { html: isoWrappedMarkup });
    } else {
      res.send(404).send('Not found')
    }
  })

}) 
cannap commented 8 years ago

Hi, my client looks so

Iso.bootstrap(function (state, node) {
    alt.bootstrap(state);
    render(
        <Router history={browserHistory}>
            {routes}
        </Router>,
       node)
});
syarul commented 8 years ago

Thanks @cannap though browserHistory does not work on recent updates, so I replace that with hashHistory

import { Router, hashHistory }  from 'react-router'

Iso.bootstrap((state, container) => {
  alt.bootstrap(state);
  render(<Router history={hashHistory }>{routes}</Router>, container)
})
syarul commented 8 years ago

@cannap do you have a gist of your code server and client as sample I get error output alt.bootstrap is not a function

cannap commented 8 years ago

dont have a repo atm you need to use your alt instance import this and not the lib itself when you have alt.js file

let Alt = require('alt')
let alt = new Alt();
Alt.debug('alt', alt);
module.exports = alt;
syarul commented 8 years ago

I have the alt instance, since I don't know where the source of the prob I delete all my node_modules and replace with the old one, turn out the problem was it if I'm using babel 6 to compile the error persist.

cannap commented 8 years ago

ah i run my server like and i use babel 6

require('babel-register');
require('./server');
syarul commented 8 years ago

If I downgrade to babel 5.x everything work but on babel 6 I will always get

TypeError: alt.bootstrap is not a function

tyronep commented 8 years ago

When you inspect the alt object, do you see a default node? You're probably mixing ES6 export with CommonJS require. This blog post goes into more detail: https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0#.nomsnevf9

For reference, my client-side render function looks like this:

import React from "react"; // 0.14.7
import ReactDOM from "react-dom"; // 0.14.7
import { browserHistory, Router } from "react-router"; // 2.0.1
import Iso from "iso"; // 5.2.0

function renderApp() {
  // Apply polyfills before loading app components
  const alt = require("../shared/alt").default; // 0.18.4
  const routes = require("./routes").default;

  Iso.bootstrap((state, container) => {
    alt.bootstrap(state);
    ReactDOM.render(<Router history={ browserHistory }>{ routes }</Router>, container);
  });
}
syarul commented 8 years ago

Thanks @tyronep, that solve the issue, and good reading btw +1