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:

  1. Server verwenden react-router um alle Anfrage
  2. react-router rufen fetchData Funktionen, die sich in jeder Reagieren Ansicht, dass entspricht der Strecke.
  3. Die Daten geholt, bevor Sie in Requisiten Reagieren die Sicht und machen es zu string
  4. Injizieren die string und abgerufenen Daten vor, die als Globale variable window.__STATE__ in HTML und liefern das HTML an den client
  5. Haben wir erfolgreich Rendern Reagieren-App vom server
  6. 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);
    }
  }
}
Schreibe einen Kommentar