Skip to content

Is ReactRailsUJS.serverRender intended to be overridable? #864

@not-an-aardvark

Description

@not-an-aardvark

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions