React_on_rails v9使得从服务器端传递道具变得轻而易举,因此当 prerender 设置为true时,服务器端渲染变得如此简单 . 但是,面对的挑战是尝试实现React Router v4 . 具有react路由器的isssue无法从服务器端传递道具

我相信从v7升级到v9的文档将清除此问题 - https://github.com/shakacode/react_on_rails/issues/809#issuecomment-334344969 . 但是在我等待的时候,我认为我们仍然可以做一些事情来解决路由问题 .

以下是重现的一些步骤:

app/javascript/bundles/RailsNg/components/ServerHome.jsx

import React from 'react';
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router';
import routes from './routes/routes';

const RailsNgOne = (props, railsContext) => {
const { location } = railsContext;

const context = {};

return (
  <StaticRouter
    location={location}
    context={context}
  >
   {routes}
  </StaticRouter>
  );
};

global.React = React
global.ReactDOMServer = ReactDOMServer

export default RailsNgOne

app/javascript/bundles/RailsNg/components/ClientHome.jsx

import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import routes from './routes/routes';

export default (props, railsContext) => {
  return (
    <Router>
      {routes}
    </Router>
  );

};

app/javascript/bundles/RailsNg/components/routes/routes.jsx

import React from 'react';
import { Route, Switch } from 'react-router';
import RailsNg from '../RailsNg';

export default (
  <Switch>
    <Route exact path="/" component={RailsNg} />
  </Switch>
);

app/javascript/bundles/RailsNg/components/RailsNg.jsx

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Footer from './Footer'
import RailsNgHeader from './RailsNgHeader';

export default class RailsNg extends React.Component {
  render(){
    return(
      <div className="landing-container">
        <div className="landing-dashboard">
          <RailsNgHeader logo={this.props.logo} />
          <div className="dashboard-container">
            <div className="dashboard-title">
              <h2>Rails</h2><h1>NG</h1>
            </div>
            <div className="rails-logo">
              <img src={this.props.railslogo} alt="railslogo" className="rails-logo" />
            </div>
            <div className="dashboard-text">
              <p>An Acive Ruby on Rails Forum.</p>
              <p>this Landing page is SSR</p>
            </div>
            <div className="dashboard-button-container">
              <a href="#">
                <div className="dashboard-button">
                  <p>GET STARTED</p>
                </div>
              </a>
            </div>
          </div>
        </div>
        <div className="dashboard-advert">
          <image src={this.props.advert} alt="advert" className="dashboard-advert"/>
        </div>
        <Footer instagram={this.props.instagram} twitter=
{this.props.twitter} medium={this.props.medium} />
      </div>
    )
  }
}

app/javascript/packs/rails-ng-bundles.js

import ReactOnRails from 'react-on-rails';

import RailsNgOne from '../bundles/RailsNg/components/ClientHome';

ReactOnRails.register({
  RailsNgOne
})

app/javascript/packs/clientRegistration.js

import ReactOnRails from 'react-on-rails';

import RailsNgOne from '../bundles/RailsNg/components/ClientHome';

ReactOnRails.register({
  RailsNgOne
})

app/views/rails_ng/index.html.erb

<%= react_component("RailsNgOne", props: @images, prerender: true, raise_on_prerender_error: true, trace: true) %>

app/views/layouts/rails_ng.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>RailsNg</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': true %>
    <%= javascript_pack_tag 'rails-ng-bundle'%>

  </head>
  <body>
    <div class="landing-Header">
      <div class="header-button-container">
        <div class="landing-button.login">
          <%= link_to "Log Out", destroy_user_session_path, method: :delete %>
        </div>
      </div>
    </div>
    <%= yield %>

  </body>
</html>

app/controllers/rails_ng_controller.rb

# frozen_string_literal: true

class RailsNgController < ApplicationController
  # before_action :authenticate_user!

  layout "rails_ng"

  def index
    @images = {
      instagram: path_to_asset('landing/server-instagram'),
      twitter: path_to_asset('landing/server-twitter'),
      medium: path_to_asset('landing/server-medium'),
      logo: path_to_asset('landing/iquest-logo.png'),
      advert: path_to_asset('landing/RailsNigeria.png'),
      railslogo: path_to_asset('landing/rails-small.png')
   }
 end

 private

 def path_to_asset(asset)
   ApplicationController.helpers.asset_path(asset)
 end
end

config/application.rb - 此文件配置为使rails从资源管道中获取saas字体 .

require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)

module Chatty
  class Application < Rails::Application

    config.load_defaults 5.1

    config.assets.paths << Rails.root.join("app", "assets", "fonts")

    if Rails.configuration.respond_to?(:sass)
      Rails.configuration.sass.tap do |config|
        config.preferred_syntax = :sass
      end
    end
  end
end

My results in Google Chrome console:

[SERVER] RENDERED RailsNgOne to dom node with id: RailsNgOne-react-component-8a9e89f0-3a29-4e82-9def-ed0dd15b091d with railsContext: {"inMailer":false,"i18nLocale":"en","i18nDefaultLocale":"en","href":"http://localhost:3000/","location":"/","scheme":"http","host":"localhost","port":3000,"pathname":"/","search":null,"httpAcceptLanguage":"en-US,en;q=0.8","serverSide":true}
createReactElement.js?46c3:40 RENDERED RailsNgOne to dom node with id: RailsNgOne-react-component-8a9e89f0-3a29-4e82-9def-ed0dd15b091d with props, railsContext: Objectadvert: "/assets/landing/RailsNigeria-19e84826196ea914bb17b5ba0d19b1a433147f64930a2d56eee88966b6fd6932.png"instagram: "/assets/landing/server-instagram-8309aeb4b134643b3849b1de08841274b887d7151c5696335cd8b22df607a4f9.png"logo: "/assets/landing/iquest-logo-8933b1ebd899e105fab35298969a54ded275285b751dc56f0314e5fe39945edd.png"medium: "/assets/landing/server-medium-7f29c9056261f92fb263996e317bd5a923a97d3867663c2f09c838e8cef2eda6.png"railslogo: "/assets/landing/rails-small-8a536281b93bba16489868c3387a2855c422e7e9f0b74e8bc09f89ea8c93738b.png"twitter: "/assets/landing/server-twitter-3f8241068c8426a8e17df940a1fd6706dacf7eca06623f5e0f440c0879a2c4d7.png"__proto__: Object Objecthost: "localhost"href: "http://localhost:3000/"httpAcceptLanguage: "en-US,en;q=0.8"i18nDefaultLocale: "en"i18nLocale: "en"inMailer: falselocation: "/"pathname: "/"port: 3000scheme: "http"search: nullserverSide: false__proto__: Object

具有react路由器的isssue无法从服务器端传递道具 . 此with-react-router-screenshot显示无法传递来自服务器的图像道具 . 这是因为 RailsNg 组件通过路由器传递 . 我没有足够的声誉来发布两个以上的链接 . 但是没有 RailsNg 组件通过反应路由器传递,图像道具从服务器端渲染 .

非常感谢您的帮助 . 谢谢 .