Skip to content

Warning "Expected server HTML to contain a matching <div> in <div>" #842

Closed
@jsbaltodano

Description

@jsbaltodano
Contributor

Well I am creating a component with
<%= react_component('NameOfComponent', {}, prerender: false) %>

and React is logging into the console
Warning "Expected server HTML to contain a matching div in div"

For what I seen it does not log it if the component is creating using render instead of hydrate

My question is how can I stop the warning.

I read #828
and then in your code

        if (typeof ReactDOM.hydrate === "function") {
          ReactDOM.hydrate(React.createElement(constructor, props), node);
        } else {
          ReactDOM.render(React.createElement(constructor, props), node);
        }

and I thought, maybe you are forcing the hydrate function.

I did force the same method but without using hydrate and the warning goes away.

System configuration

**Webpacker version 3.0.2:
**React-Rails version 2.4.1:
**Rails version 5.1.4:
**Ruby version2.4.2:

Activity

BookOfGreg

BookOfGreg commented on Nov 22, 2017

@BookOfGreg
Member

We probably do want to be more subtle about when we hydrate vs render.
In the longer term I'd like to add a data attribute when it's pre-rendered so I can make the UJS choose between rendering and hydrating for each component. For now Hydrate is a better default than render though it does have some side effects.

I'd welcome a PR to choose hydrate or render based on if a component was pre-rendered for if anyone has time to contribute.

dwightwatson

dwightwatson commented on Nov 26, 2017

@dwightwatson

Spotted this one as well. We're not pre-rendering any components and this error has started popping up in the console.

phuctm92

phuctm92 commented on Nov 27, 2017

@phuctm92

I'm newbie at this gem. first of all, I installed this gem with webpacker and i also meet this issue. So how can I resolve, please tell me detail because I don't understand you said above. thanks in advanced.

jsbaltodano

jsbaltodano commented on Nov 27, 2017

@jsbaltodano
ContributorAuthor

Well, it is an issue within the gem but the idea to hack it for a quick check is

Create the file component_mount.rb inside config\initializers

Write the same as the original file but you could add
data[:hydrate] = 't' if prerender_options

below
data[:react_props] = (props.is_a?(String) ? props : props.to_json)

This would work as a data param for JS to check if ReactDOM.hydrate() must be use or to use the ReactDOM.render() method.

Now, append this to your \app\javascript\packs\application.js

import React from 'react';
import ReactDOM from 'react-dom';

ReactRailsUJS.mountComponents = function(searchSelector) {
    var ujs = ReactRailsUJS;
    ujs.RENDER_ATTR = 'data-hydrate';
    var nodes = ujs.findDOMNodes(searchSelector);

    for (var i = 0; i < nodes.length; ++i) {
      var node = nodes[i];
      var className = node.getAttribute(ujs.CLASS_NAME_ATTR);
      var constructor = ujs.getConstructor(className);
      var propsJson = node.getAttribute(ujs.PROPS_ATTR);
      var props = propsJson && JSON.parse(propsJson);
      var hydrate = node.getAttribute(ujs.RENDER_ATTR);

      if (!constructor) {
        var message = "Cannot find component: '" + className + "'"
        if (console && console.log) {
          console.log("%c[react-rails] %c" + message + " for element", "font-weight: bold", "", node)
        }
        throw new Error(message + ". Make sure your component is available to render.")
      } else {
      	// ReactDOM.render(React.createElement(constructor, props), node);
        if (hydrate && typeof ReactDOM.hydrate === "function") {
          ReactDOM.hydrate(React.createElement(constructor, props), node);
        } else {
          ReactDOM.render(React.createElement(constructor, props), node);
        }
      }
    }
  }

Reset your server.

BookOfGreg

BookOfGreg commented on Nov 27, 2017

@BookOfGreg
Member

@jsbaltodano , @dwightwatson and @phuctm4192 sorry for causing you all a bug. Thanks a bunch for your help fixing and reporting it all.
I'll put a release out soon once Travis has run with the new patch in it as v2.4.3

Toske94

Toske94 commented on Sep 13, 2018

@Toske94

I'm new in this, can someone explain me why I got this error

The script that I use is returning a picture, but sometimes the picture is not showing and I got this error:

Expected server HTML to contain a matching in .

import React from 'react';
import {Menu} from 'semantic-ui-react';
import { Link } from '../routes';

export default (props) => {
    return (
      <Menu borderless id="logo">
        <script 
            type="text/javascript" 
            src="https://example.com/link/script/" >
        </script>
    </Menu>
    );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @BookOfGreg@dwightwatson@jsbaltodano@Toske94@phuctm92

        Issue actions

          Warning "Expected server HTML to contain a matching <div> in <div>" · Issue #842 · reactjs/react-rails