react gratis fazt desde curso javascript node.js express reactjs react-router

javascript - gratis - react desde 0



Representación del lado del servidor con reaccionar, reaccionar enrutador y expresar (1)

Estoy tratando de configurar el renderizado del lado del servidor para mi aplicación reaccionar y estoy tratando de usar el gran módulo react-router para permitirle manejar situaciones que no sean js (algunos rastreadores, cuando un usuario ha apagado js para algunos razón). Sin embargo, estoy teniendo problemas. He estado usando la gran respuesta aquí https://stackoverflow.com/a/28558545/3314701 como una especie de guía, pero me están arrojando errores extraños. react.renderToString() un Syntax Error persistente cuando intento usar react.renderToString() . ¿Estoy configurando la representación del lado del servidor de forma incorrecta, falta algo obvio, o cualquier otra cosa?

Mi configuración:

Servidor Express realmente básico

require(''babel/register''); var app = express(); // misc. express config... var Router = require(''react-router''), routes = require(''../jsx/app'').routes, React = require(''react''); app.use(function(req, res, next) { var router = Router.create({location: req.url, routes: routes}); router.run(function(Handler, state) { console.log(Handler); var html = React.renderToString(<Handler/>); return res.render(''react_page'', {html: html}); }); });

Componente de reacción de nivel superior <App/>

// Shims require(''intl''); require(''es5-shim''); var React = require(''react/addons''), Router = require(''react-router''), Nav = require(''./nav''), injectTapEventPlugin = require("react-tap-event-plugin"), window.React = React; // export for http://fb.me/react-devtools // Intl var ReactIntl = require(''react-intl''), IntlMixin = ReactIntl.IntlMixin; var Route = Router.Route, DefaultRoute = Router.DefaultRoute, NotFoundRoute = Router.NotFoundRoute, RouteHandler = Router.RouteHandler; var App = React.createClass({ mixins: [IntlMixin], getInitialState: function() { return { connected: false, loaded: false, user: true }; }, render: function() { return ( <div className="container-fluid"> <Nav/> <RouteHandler/> <Footer/> </div> ); } }); var routes = ( <Route name="Home" path="/" handler={App}> <DefaultRoute name="Welcome " handler={Welcome}/> <Route name="Bar" path="/bar" handler={Bar}> <Route name="foo" path="/foo" handler={Foo}></Route> </Route> ); Router.run(routes, Router.HistoryLocation , function(Handler) { React.render(<Handler/>, document.getElementById(''app'')); }); module.routes = routes;

salida:

flo-0,1,2 (err): <div className="progressbar-container" > flo-0,1,2 (err): ^ flo-0,1,2 (err): SyntaxError: Unexpected token < flo-0,1,2 (err): at exports.runInThisContext (vm.js:73:16) flo-0,1,2 (err): at Module._compile (module.js:443:25) flo-0,1,2 (err): at Module._extensions..js (module.js:478:10) flo-0,1,2 (err): at Object.require.extensions.(anonymous function) [as .js] (/Users/user/Code/foobar/apps/flo/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:161:7) flo-0,1,2 (err): at Module.load (module.js:355:32) flo-0,1,2 (err): at Function.Module._load (module.js:310:12) flo-0,1,2 (err): at Function.<anonymous> (/Users/user/.nvm/versions/node/v0.12.4/lib/node_modules/pm2/node_modules/pmx/lib/transaction.js:62:21) flo-0,1,2 (err): at Function.cls_wrapMethod (/Users/user/Code/foobar/apps/bar/node_modules/newrelic/lib/shimmer.js:230:38) flo-0,1,2 (err): at Function.<anonymous> (/Users/user/Code/foobar/apps/bar/node_modules/pmx/lib/transaction.js:62:21) flo-0,1,2 (err): at Module.require (module.js:365:17) flo-0,1,2 (err): at require (module.js:384:17)


Entonces, termine resolviendo este yo mismo. El error que estaba obteniendo era de un componente anidado no renderizado, que es la razón por la cual el motor js se quejaba de un < char aleatorio.

Y ahora a mi configuración expresa. Para aquellos que no saben cómo reaccionar se puede usar con la representación del lado del servidor, es bastante sencillo: se puede usar Node o io.js para llamar al método renderToString() React en un componente y luego enviarlo al cliente solicitante. Probablemente ya hayas escuchado los beneficios que este enfoque trae, pero para aquellos que no saben:

  1. obtienes más simpatía por SEO, aunque Google ya puede ejecutar JS en sus rastreadores; esto es más o menos una apuesta más segura
  2. Fallback para situaciones no js. Si la secuencia de comandos de la aplicación se carga lentamente, aún puede mostrar la página real a su cliente y no hacer que espere mientras mira una pantalla en blanco. Esto también permite a una persona con JS inhabilitada en su navegador interactuar con la aplicación en su mayor parte; los enlaces seguirán funcionando, los formularios aún pueden enviarse, & c.
  3. Puede obtener los beneficios adicionales de compartir código entre el cliente y el servidor. No hay nada necesariamente increíble al respecto, aparte del hecho de que la complejidad disminuye y, como tal, obtienes todos los beneficios de una menor complejidad (potencialmente menos acoplamiento, facilidad de mantenimiento más sencilla, mayor simplicidad en la estructura, isomorfismo, etc.)
  4. Otro beneficio adicional es la capacidad de usar la API de historia html5 de reac-router en lugar de las molestas cosas de fragmentos de hash que de otra manera se deben usar.

Incluso podría volverse loco con este enfoque y manejar cosas como marcadores de posición para su aplicación mientras carga o proporcionar otros mecanismos de retroalimentación para un estado de carga lenta (al estilo de Facebook mientras se carga).

El enfoque básico funciona aproximadamente de la siguiente manera:

  1. En el arranque, la aplicación de nodo crea una instancia de routes.jsx -enrutador basada en routes.jsx
  2. La solicitud va al servidor, que luego usa la req.path '' req.path '' para proporcionar una cadena de ruta para que el router-reacción pueda manejarla.
  3. Reaccionar enrutador luego coincide con la ruta proporcionada e intenta representar el componente correspondiente para que el expreso envíe de regreso.
  4. React envía la respuesta html y su cliente pinta algo independientemente de la velocidad del script de su aplicación. Servimos a los nuestros a través de un gran CDN, pero incluso con la mejor distribución y compresión, las redes lentas de todos modos dejarían a las personas con una pantalla temporalmente en blanco.
  5. Después de haber cargado el script de la aplicación necesaria, React puede usar el mismo archivo routes.jsx para hacerse cargo y generar html con react-router de aquí en adelante. Otro beneficio aquí es que el código de su aplicación se puede almacenar en caché y las futuras interacciones con suerte ni siquiera tendrán que depender de otra llamada.

Un punto más que vale la pena mencionar: uso webpack para agrupar mi código de reacción y ahora browser.jsx es el punto de entrada. Antes de refactorizar para la representación del lado del servidor, anteriormente era app.jsx ; es posible que necesite volver a configurar su estructura para acomodar lo que se procesa donde. :)

Código:

Browser.jsx

const React = require(''react''); const Router = require(''react-router'').Router; const hist = require(''history''); const routes = require(''./routes''); const newHistory = hist.createHistory(); React.render(<Router history={newHistory}>{routes}</Router>, window.document);

App.js (servidor express) :

//...other express configuration const routes = require(''../jsx/routes''); const React = require(''react''); const {RoutingContext, match} = require(''react-router''); const hist = require(''history''); app.use((req, res, next) => { const location = hist.createLocation(req.path); match({ routes: routes, location: location, }, (err, redirectLocation, renderProps) => { if (redirectLocation) { res.redirect(301, redirectLocation.pathname + redirectLocation.search); } else if (err) { console.log(err); next(err); // res.send(500, error.message); } else if (renderProps === null) { res.status(404) .send(''Not found''); } else { res.send(''<!DOCTYPE html>'' + React.renderToString(<RoutingContext {...renderProps}/>)); } }); }); //...other express configuration

Routes.jsx

<Route path="/" component={App}> <DefaultRoute component={Welcome}/> <Route path="dashboard" component={Dashboard}/> <Route path="login" component={Login}/> </Route>

App.jsx

<html> <head> <link rel="stylesheet" href="/assets/styles/app.css"/> </head> <body> <Navigation/> <RouteHandler/> <Footer/> <body/> </html>

Enlaces Útiles: