script react helmet create app javascript reactjs react-router

javascript - helmet - react meta tags



Cómo manejar la solicitud de publicación en el enrutador Isomorphic React+React (1)

Obteniendo datos "POST" en el cliente

En el lado del cliente, obtiene datos POST al extraer valores de las entradas de su formulario de una manera que corresponde a lo que habría recibido en el servidor si el formulario hubiera sido enviado normalmente.

Uso de datos POST

Así que ahora tiene sus datos POST, pero sigue teniendo el problema de que no hay forma de incluir los datos POST en sus enlaces de transición en React Router 0.13.xy versiones anteriores. Creé una solicitud de extracción para esta función que ahora se ha cerrado porque se incluyó como parte de la reescritura para la próxima versión v1.0.

La esencia de esto es que las ubicaciones ahora tienen un objeto de estado para eliminar cualquier información adicional que necesite sobre la solicitud / transición actual (las dos son análogas) que se manejan:

  • En el servidor, usted está tratando con una solicitud a la vez, por lo que crea una ubicación estática con datos de req.body
  • En el cliente, se pasa el objeto de estado (que contiene datos de formulario extraídos) a transitionTo() .

Ahora su enlace de transición es capaz de recibir los mismos datos de formulario en ambos entornos. Si las cosas van bien, ¡genial! Si las cosas no van bien, necesita una forma de pasar los errores y volver a renderizar el formulario. ¡Nuevo objeto estatal al rescate de nuevo! Use transition.redirect() y pase tanto los datos de entrada como los errores y ahora tiene todo lo que necesita para renderizar en ambos lados.

No voy a entrar en detalles más específicos ahora porque v1.0 todavía está en versión beta y v0.13.x no tiene la API necesaria para hacer esto de todos modos, pero tengo un repositorio que utiliza la solicitud de extracción anterior para implementar este flujo de trabajo con 0.13.x que podría mirar mientras tanto:

  • isomorphic-lab : el README ofrece una visión general de cómo encajan las cosas.

Aquí hay algunos diagramas de flujo del proceso, también:

Servidor POST con errores y redisplay.

Cliente POST con errores y redisplay.

También he creado algunos módulos reutilizables relacionados con este escenario:

  • get-form-data obtiene datos de las entradas de un formulario en el formato en el que se hubieran enviado.
  • react-auto-form proporciona <AutoForm> , que puede usar en lugar de <form> para recibir todos los datos de las entradas de un formulario como un argumento para su controlador onSubmit
  • react-router-form , que es <form> lo que React Router <Link> es <a> : maneja una transición a la action dada, el method paso y el estado del body (datos del formulario); esto se actualizará para v1 .0 pronto.

Quiero crear la aplicación Isomorphic react + react-router y después de unos días en Google, ahora puedo lograr la aplicación isomórfica que solo maneja la solicitud GET.

Esto es lo que he hecho hasta ahora:

  1. Servidor de uso react-router para manejar todas las solicitudes
  2. react-router llamará a fetchData funciones fetchData que residen en cada Vista de Reacción que coincida con la ruta.
  3. Establezca los datos recuperados anteriormente en las propiedades de la Vista de Reacción y conviértalos en una string
  4. Inyecte la string y los datos obtenidos antes como window.__STATE__ variable global window.__STATE__ en HTML y entregue el HTML al cliente
  5. Hemos renderizado exitosamente la aplicación React desde el servidor.
  6. Cuando el cliente termine de cargar nuestra aplicación React javascript, intentará renderizar. Pero pasamos el estado desde la window.__STATE__ como accesorios de nuestra aplicación React, y React no volverá a reproducirse porque el estado es el mismo

El problema es que no funcionará con la solicitud POST / PUT / DELETE / WHATEVER. Cuando se maneja la solicitud GET, react-router tiene información sobre params y query . Por ejemplo, si tenemos una ruta: /user/:uid y el cliente solicita esta url: /user/1?foo=bar , entonces los params serían: {uid: 1} y la query sería {foo: ''bar''}

react-router luego puede pasarlo a la función fetchData para que conozca el usuario con uid de 1 y haga lo que sea con la consulta foo .

Mientras se encuentra en la solicitud POST, react-router no conoce los parámetros POST. En el servidor, por supuesto, podríamos pasar los parámetros POST a la función fetchData , pero ¿qué pasa con el cliente? No sabe cuáles son los parámetros POST.

¿Hay alguna forma en que el servidor pueda decirle al Cliente acerca de los parámetros POST? A continuación se muestra un ejemplo de mi vista de inicio de sesión. Deseo que cuando el usuario envíe el formulario, el servidor muestre un mensaje de error en caso de error, o lo redirija al panel de control en caso de éxito

fetchData.js

import whenKeys from ''when/keys''; export default (authToken, routerState) => { var promises = routerState.routes.filter((match) => { return match.handler.fetchData; }).reduce((promises, match) => { promises[match.name] = match.handler.fetchData(authToken, routerState.params, routerState.query); return promises; }, {}); return whenKeys.all(promises); }

server.js

... app.use((req, res) => { const router = Router.create({ routes, location: req.originalUrl, onError: next, onAbort: (abortReason) => { next(abortReason); } }); router.run((Handler, state) => { fetchData(authToken, state).then((data) => { // render matched react View and generate the HTML // ... }) }); }); ...

login.jsx

import React from ''react''; import DocumentTitle from ''react-document-title''; import api from ''./api''; export default class Login extends React.Component { constructor(props) { super(props); // how to fill this state with POST parameters on error? // how to redirect on success? // and remember that this file will be called both from server and client this.state = { error: '''', username: '''', password: '''' }; } // I saw some people use this function, but it''ll only work if // the form''s method is GET static willTransitionTo(transition, params, query) { // if only we could read POST parameters here // we could do something like this transition.wait( api.post(''/doLogin'', postParams).then((data) => { transition.redirect(`/dashboard`); }); ); } render() { return ( <DocumentTitle title="Login"> <div className="alert alert-danger">{this.state.error}</div> <form method="post"> <input type="text" name="username" value={this.state.username} onChange={this._onFieldChange(''username'')} placeholder="Username" /><br /> <input type="password" name="password" value={this.state.password} onChange={this._onFieldChange(''password'')} placeholder="Password" /><br /> <button type="submit">Login</button> </form> </DocumentTitle> ); } _onFieldChange(name) { var self = this; return (e) => { e.preventDefault(); var nextState = {}; nextState[name] = e.target.value; self.setState(nextState); } } }