Wie Behandeln Post-Anforderung in Isomorph Reagieren + Reagieren die Router-Anwendung
Ich bauen will Isomorph react
+ react-router
Anwendung und nach ein paar Tagen googlen, jetzt kann ich erreichen isomorph Anwendung, die nur mit GET-Requests.
Hier ist, was ich bisher getan habe:
- Server verwenden
react-router
um alle Anfrage react-router
rufenfetchData
Funktionen, die sich in jeder Reagieren Ansicht, dass entspricht der Strecke.- Die Daten geholt, bevor Sie in Requisiten Reagieren die Sicht und machen es zu
string
- Injizieren die
string
und abgerufenen Daten vor, die als Globale variablewindow.__STATE__
in HTML und liefern das HTML an den client - Haben wir erfolgreich Rendern Reagieren-App vom server
- Wenn der client fertig geladen ist unsere Reagieren-App-javascript ist, wird es versuchen zu machen. Aber wir passieren den Zustand von
window.__STATE__
als Requisiten unserer App Reagieren, und Reagieren nicht re-Rendern, weil der Staat die gleichen
Das problem ist, es funktioniert nicht mit POST/PUT/DELETE/WAS auch immer Wunsch. Beim Umgang mit GET-Anforderung react-router
Informationen über params
und query
. Zum Beispiel, wenn wir eine route: /user/:uid
- und client-Anfrage diese url: /user/1?foo=bar
, dann params
wäre: {uid: 1}
und query
wäre {foo: 'bar'}
react-router
dann kann es passieren, nach unten zu fetchData
Funktion, so dass es weiß, zu Holen Nutzer mit uid
1 und tun, was mit foo
Abfrage.
Während in der POST-Anforderung react-router
doesn ' T wissen über die POST-Parameter. Auf dem Server, natürlich könnten wir passieren die POST-Parameter zu fetchData
Funktion, aber was ist mit dem Client? Er weiß nicht, was die POST-Parameter sind.
Gibt es eine Möglichkeit, dass der server dem Client mitteilen, über die POST-Parameter? Unten ist ein Beispiel, meine Login-Ansicht. Ich möchte, wenn der Benutzer das Formular senden, wird der server rendert Fehlermeldung auf Fehler, oder leiten Sie Sie zu dashboard auf Erfolg.
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);
}
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Immer "POST" - Daten auf dem client
Auf der client-Seite, erhalten Sie POST-Daten durch extrahieren der Werte aus dem Formular die Eingaben in einer Weise, die dem entspricht, was Sie erhalten hätten, auf den server hatte das Formular schon eingereicht normal.
Mit POST-Daten
So, jetzt haben Sie Ihre POST-Daten, aber Sie haben immer noch das problem, dass es keine Art und Weise zu ernähren, die POST-Daten in Ihrem übergang Haken im Router Reagieren 0.13.x und früher. Ich erstellte eine pull-request für diese Funktion die wurde nun geschlossen, denn es wurde als Teil des neu zu schreiben für die kommende v1.0 release.
Das wesentliche ist, dass die Orte haben nun ein state-Objekt für squireling entfernt alle zusätzlichen Daten, die Sie benötigen, über die aktuelle Anfrage/übergang (die beiden sind analagous) behandelt:
req.body
transitionTo()
.Nun Ihren übergang Haken ist, empfangen der gleichen form Daten in beiden Umgebungen. Wenn die Dinge gut gehen, große! Wenn die Dinge nicht gut laufen, müssen Sie einen Weg zu passieren Fehler und re-render form wieder. Neues state-Objekt erneut zu Hilfe! Verwenden
transition.redirect()
und pass Eingabe von Daten und Fehler, und Sie haben jetzt alles, was Sie brauchen, um das Rendern auf beiden Seiten.Ich werde nicht in die Details, gerade jetzt, weil v1.0 ist immer noch in der beta und v0.13.x nicht die notwendige API zu tun, das sowieso, aber ich habe ein repository, das verwendet die pull-Anforderung vor, um die Implementierung dieses workflow mit 0.13.x, die Sie sehen konnte in der Zwischenzeit:
Hier sind einige grobe Flussdiagramme des Prozesses, zu:
Server POST-mit Fehlern und wieder
- Client POST-mit Fehlern und wieder
Habe ich auch ein paar wiederverwendbare Module für dieses Szenario:
<AutoForm>
, die Sie stattdessen verwenden können von<form>
erhalten Sie alle Daten aus einem Formular die Eingaben als argument für seineonSubmit
handler<form>
was Reagieren Routers<Link>
ist<a>
- es behandelt das auslösen einer transition, die zu dem gegebenenaction
vorbeimethod
undbody
(form data) Staat - wird es ein Update für v1.0 bald.<AutoForm>
undCONSTRUCT
sind wirklich schöne Ideen.