question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is ReactRailsUJS.serverRender intended to be overridable?

See original GitHub issue

Steps to reproduce

N/A

Expected behavior

N/A

Actual behavior

N/A

System configuration

Sprockets or Webpacker version: N/A React-Rails version: 2.4.3 Rect_UJS version: 2.4.3 Rails version: 4.2.8 Ruby version: 2.4.3


I’m trying to set up server rendering on a project that uses react-rails along with styled-components. styled-components needs to be able to add a <style> tag to the HTML, and it has an API for use with server-side rendering which can be used to generate an appropriate <style> tag as a string.

My goal is to be able to render the <style> tag along with the component HTML, so that the prerendered HTML has styling before the JavaScript loads on the client. Unfortunately, it’s not easy to do this with the current react-rails API, because the react_component helper always returns only the one rendered component without any additional HTML. I was able to get it to work by monkeypatching ReactRailsUJS.serverRender:

import { ReactDOMServer } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';

ReactRailsUJS.serverRender = function(renderFunction, componentName, props) {
  const ComponentConstructor = this.getConstructor(componentName);
  const stylesheet = new ServerStyleSheet();
  const wrappedElement = stylesheet.collectStyles(<ComponentConstructor {...props} />);
  const text = ReactDOMServer[renderFunction](wrappedElement);

  // prepend the style tags to the component HTML
  return stylesheet.getStyleTags() + text;
};

I’d like to avoid monkeypatching the ReactRailsUJS object in production, since I’m relying on undocumented behavior that could change in a future release. However, it doesn’t seem like there is another way to do this while still using react-rails to prerender components. I noticed that ReactRailsUJS.getConstructor is documented to be patchable – would it be possible to explicitly make serverRender patchable as well? Alternatively, is there another API I should use to prerender style tags?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
bakunyocommented, Jun 5, 2018

@reywright I tried this monkey patch in my app, and succeeded SSR of styles. In my code, changed import like below.

- import { ReactDOMServer } from "react-dom/server";
+ import ReactDOMServer from "react-dom/server";

And full of my server_rendering.js is

// By default, this pack is loaded for server-side rendering.
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
import React from "react";
import ReactDOMServer from "react-dom/server";
import { ServerStyleSheet } from "styled-components";

const componentRequireContext = require.context("components", true);
const ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);

ReactRailsUJS.serverRender = function(renderFunction, componentName, props) {
  const ComponentConstructor = this.getConstructor(componentName);
  const stylesheet = new ServerStyleSheet();
  const wrappedElement = stylesheet.collectStyles(
    <ComponentConstructor {...props} />
  );
  const text = ReactDOMServer[renderFunction](wrappedElement);

  // prepend the style tags to the component HTML
  return stylesheet.getStyleTags() + text;
};
1reaction
Undistractioncommented, Aug 13, 2018

@bakunyo Thanks for taking the time to document your approach. I feared something like this would be the solution. I think I’m going to open up a feature request for an API allowing a more sensible approach.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React-rails: integrate React.js with Rails Views and Controllers
React-rails: Integrate React.js with Rails views and controllers, the asset pipeline, or webpacker. React-Rails is a flexible tool to use React with Rails....
Read more >
Using renderToNodeStream with react-rails / webpacker
I'm working on an app using react-rails / webpacker, with a rails server and React frontend. On top of this, we are also...
Read more >
Better Reusable React Components with the Overrides Pattern
If you've been watching the React ecosystem the past few years, you've surely encountered one of the numerous open source reusable component ...
Read more >
Integrate React.js with Rails views | Frontend Framework library
This is intended to give you an instant insight into react-rails implemented ... Remove previous event handlers and add new ones: ReactRailsUJS.
Read more >
The react-rails from reactjs - GithubHelp
If require fails to find your component, ReactRailsUJS falls back to the global namespace, described in ... You can override the React build...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found