Как я могу получить параметры реакции-маршрутизатора v4, определенные с экспресс-на стороне сервера - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь получить :userId "Альберт" из этого URL http://localhost:5000/search/albert?query=al&page=1 на стороне сервера, но не получилось, что я могу сделать, чтобы правильно определить параметры response-router в node.js с помощью express?

rout.js

[
  {
    path: '/search/:userId',
    component: Search,
  }, {
    path: '/search',
    component: Search,
  }
  ... 
]

server.js

server.get('*', async (req, res, next) => {
  const pageData = await routes
  .filter(route => matchPath(req.path, route))
  .map((route) => {
    console.log(route)
    return route.component
  })
}

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Путь React-Router

React Router V4 действительно включает способ извлечения параметров данных на стороне сервера, используя их функцию matchPath () , используя стандартную реализацию параметров , "/path-name/:param" сопоставление маршрутов.

В этом случае это позволяет мне сделать много серверных вещей на основе параметра, прежде чем экспресс-приложение ответит данными страницы.

ПРИМЕЧАНИЕ : это, вероятно, не самая базовая реализация, но это урезанная версия моей полной реализации реагирования на SSR, в которой используется matchPath().

Требования

  • Приложение реагирования на стороне сервера
  • React-router-dom v4
  • Файл централизованных маршрутов (потому что SSR)
  • Сервер приложений Express (мое приложение Express размещено на Firebase )

В этом примере серверное экспресс-приложение пытается запустить функцию «initialAction» в каждом компоненте во время загрузки новой страницы. Он передает обещание разрешения и отклонения, чтобы знать, когда функция завершена, и объект запроса, который может содержать полезные параметры, которые мы можем извлечь с помощью matchPath(). Это делается для каждого соответствующего маршрута, опять же, используя matchPath().

Routes.js Пример

Где :id - это параметр "id" в URL.

const routes = [
    {
        path: "/news-feed/:id",
        component: NewsFeed,
        exact: true
    },
]

export default routes;

Пример компонента

Просто показывает функцию initialAction() в компоненте

import { Link, matchPath } from 'react-router-dom';

class NewsFeed extends Component {

    // Server always passes ability to resolve, reject in the initial action
    // for async data requirements. req object always passed from express to
    // the initial action.
    static initialAction(resolve, reject, req) {

        function getRouteData() {
            let matchingRoute = routes.find(route => {
                return matchPath(req.path, route);
            });
            console.log("Matching Route: ", matchingRoute);

            return matchPath(req.path, matchingRoute);
        }

        let routeData = getRouteData();
        console.log("Route Data: ", routeData);
    }

/** REST OF COMPONENT **/

Выход Console.log для URL www.example.com/news-feed/test будет

Route Data:  { path: '/news-feed/:id',
  url: '/news-feed/test',
  isExact: true,
  params: { id: 'test' } }

Как вы можете видеть, мы нашли наш параметр на стороне сервера без использования регулярных выражений. matchPath() сделал работу за нас. Мы можем использовать красивые, чистые URL.

Серверный index.js

Где вызывается начальное действие, с обещанием разрешить, отклонить и запросить объекты. Имейте в виду, что это пример хостинга firebase и может отличаться для разных хостинг-провайдеров - ваш метод для вызова функции initialAction также может отличаться .

import React from "react";
import ReactDOMServer from 'react-dom/server';
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { StaticRouter, matchPath } from "react-router-dom";
import routes from "../shared/components/App/routes.js";
import express from "express";
import * as functions from "firebase-functions";

// Import Components, Reducers, Styles
import App from "../shared/components/App";
import reducers from "../shared/reducers";

// Prepare our store to be enhanced with middleware
const middleware = [thunk];
const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore);

// Create store, compatible with REDUX_DEVTOOLS (chrome extension)
const store = createStoreWithMiddleware(reducers);

// Implement cors middleware to allow cross-origin
const cors = require('cors')({ origin: true });

const app = express();
app.get('**', (req, res) => {

    cors(req, res, () => {
        // Finds the component for the given route, runs the "initial action" on the component
        // The initialAction is a function on all server-side renderable components that must retrieve data before sending the http response
        // Initial action always requires (resolve, reject, req), and returns a promise.
        const promises = routes.reduce((acc, route) => {
            if (matchPath(req.url, route) && route.component && route.component.initialAction) {
                acc.push(new Promise(function (resolve, reject) {
                    // console.log("Calling initial action...");
                    store.dispatch(route.component.initialAction(resolve, reject, req));
                }));
            }
            return acc;
        }, []);

        // Send our response only once all promises (from all components included in the route) have resolved
        Promise.all(promises)
            .then(() => {
                const context = {};
                const html = ReactDOMServer.renderToString(
                    <Provider store={store}>
                        <StaticRouter location={req.url} context={context}>
                            <App />
                        </StaticRouter>
                    </Provider>
                );
                const preloadedState = store.getState();
                res.status(200).send(renderFullPage(html, preloadedState));

            })
            .catch(function (error) {
                console.log("Promise error at server", error);
            });
    });
});

module.exports = functions.https.onRequest(app);
0 голосов
/ 09 мая 2018

Просто использовал пример приложения node.js для создания server.js, который может быть похож на

const express = require('express')
const app = express()

app.get('/search/:userid', (req, res) => res.json({ key: `Hello World for search with id=${req.params.userid}` }))

app.get('/search', (req, res) => res.send('Hello World!i for search'))

app.get('*', (req, res) => res.send('Hello World!'))

app.listen(3000, () => console.log('Example app listening on port 3000!'))

Для номера страницы и других параметров URL вы можете сделать как

req.query['page'] 

для получения параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...