0

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

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

以下是一些重现的步骤:

应用程序/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

应用程序/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>
  );

};

应用程序/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>
);

应用程序/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>
    )
  }
}

应用程序/javascript/packs/rails-ng-bundles.js

import ReactOnRails from 'react-on-rails';

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

ReactOnRails.register({
  RailsNgOne
})

应用程序/javascript/packs/clientRegistration.js

import ReactOnRails from 'react-on-rails';

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

ReactOnRails.register({
  RailsNgOne
})

应用程序/视图/rails_ng/index.html.erb

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

应用程序/视图/布局/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>

应用程序/控制器/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

我在 Google Chrome 控制台中的结果:

[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

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

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

4

0 回答 0