Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jsbaltodano opened this issue Nov 21, 2017 · 6 comments
Closed

Comments

@jsbaltodano
Copy link
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:

@BookOfGreg
Copy link
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
Copy link

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

@phuctm92
Copy link

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
Copy link
Contributor Author

jsbaltodano commented Nov 27, 2017

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
Copy link
Member

BookOfGreg commented Nov 27, 2017

@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
Copy link

Toske94 commented Sep 13, 2018

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
Projects
None yet
Development

No branches or pull requests

5 participants