Как обработать почтовый запрос в изоморфном приложении React + React Router

Я хочу построить Изоморфныйreact + react-router приложение и после нескольких дней поиска в Google, теперь я могу добиться изоморфного приложения, которое обрабатывает только запрос GET.

Вот что я сделал до сих пор:

Использование сервераreact-router обрабатывать все запросыreact-router позвонюfetchData функции, которые находятся в каждом React View, который соответствует маршруту.Установите данные, выбранные ранее, в подпорки React View и отобразите их вstringВведитеstring и данные извлекаются как глобальная переменнаяwindow.__STATE__ в HTML и доставить HTML клиентуМы успешно представили приложение React с сервера.Когда клиент закончит загрузку нашего JavaScript-приложения React, он попытается выполнить рендеринг. Но мы передаем состояние отwindow.__STATE__ как реквизиты нашего приложения React, и React не будет повторно визуализировать, потому что состояние одинаково

Проблема в том, что он не будет работать с запросом POST / PUT / DELETE / WHATEVER. При обработке запроса GET,react-router иметь информацию оparams а такжеquery, Например, если у нас есть маршрут:/user/:uid и клиент запрашивает этот URL:/user/1?foo=bar, затемparams было бы:{uid: 1} а такжеquery было бы{foo: 'bar'}

react-router затем может передать егоfetchData функция, поэтому он будет знать, чтобы выбрать пользователя сuid из 1 и делать сfoo запрос.

В то время как в запросе POST,react-router не знает о параметрах POST. На сервере, конечно, мы могли бы передать параметры POSTfetchData функция, а как насчет клиента? Он не знает, что такое параметры POST.

Есть ли способ, чтобы сервер мог сообщить клиенту о параметрах POST? Ниже приведен пример моего вида входа в систему. Я хочу, чтобы когда пользователь отправлял форму, сервер отображал сообщение об ошибке или перенаправлял его на панель мониторинга в случае успеха.

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);
    }
  }
}

Ответы на вопрос(1)

Ваш ответ на вопрос