Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ReactDOM.hydrate with ClientOnly #521

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
igorroch opened this issue Mar 22, 2018 · 8 comments
Closed

ReactDOM.hydrate with ClientOnly #521

igorroch opened this issue Mar 22, 2018 · 8 comments

Comments

@igorroch
Copy link

igorroch commented Mar 22, 2018

There is a console error when we try to render component with parameter clientOnly: true

react-dom.development.js:894 Warning: Expected server HTML to contain a matching <div> in <div>.

@Html.React("ReactWorld", new { name = "World" }, clientOnly: true)

Minimal repo to reproduce: https://github.com/igorroch/React.NET-issue-521

https://stackoverflow.com/questions/46443652/react-16-warning-expected-server-html-to-contain-a-matching-div-in-body
says that "If your application is not ssr, please use ReactDOM.render to start"

But now RenderJavaScript() uses only ReactDOM.hydrate for all components.

@igorroch igorroch changed the title React.hydrate with ClientOnly ReactDOM.hydrate with ClientOnly Mar 22, 2018
@dustinsoftware
Copy link
Member

dustinsoftware commented Mar 24, 2018 via email

@suhailnaw
Copy link
Contributor

@igorroch are you working on a fix? If not, I'm looking to make my first open source contribution and can take a stab at it!

@igorroch
Copy link
Author

@suhailnaw Not working now. I wish to do it, but do not have free time at all. Feel free to take it

@dustinsoftware
Copy link
Member

Hi @suhailnaw 👋 let me know if you'd like some help on this one! If you don't have time either let me know and I'll take care of it.

@suhailnaw
Copy link
Contributor

Hey @dustinsoftware, I do need some help! Is the aim to remove error because now we should be using ReactDOM.hydrate for all cases?

@dustinsoftware
Copy link
Member

Per the React docs, hydrate should be called on a component that has been server rendered. When server-render is skipped, calling render is appropriate.

Add ClientOnly as a property to ReactComponent. When ReactEnvironment.CreateComponent is called, ClientOnly needs to be set:

var component = new ReactComponent(this, _config, _reactIdGenerator, componentName, containerId)
{
Props = props,
ServerOnly = serverOnly
};

When RenderJavaScript is called in ReactComponent, ClientOnly should be checked. If true, ReactDOM.render should be written to the script instead of ReactDOM.hydrate.

public virtual void RenderJavaScript(TextWriter writer)
{
writer.Write("ReactDOM.hydrate(");
WriteComponentInitialiser(writer);
writer.Write(", document.getElementById(\"");
writer.Write(ContainerId);
writer.Write("\"))");
}

Let's make sure to add a unit test for this as well. Here's an example one you can duplicate:

[Fact]
public void RenderJavaScriptShouldCallRenderComponent()
{
var environment = new Mock<IReactEnvironment>();
var config = new Mock<IReactSiteConfiguration>();
var reactIdGenerator = new Mock<IReactIdGenerator>();
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
{
Props = new { hello = "World" }
};
var result = component.RenderJavaScript();
Assert.Equal(
@"ReactDOM.hydrate(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))",
result
);
}

@suhailnaw
Copy link
Contributor

Hey @dustinsoftware , I just made my first open source PR :D Could you please give me some feedback? I really appreciate all your help and aim to wrap this issue asap!

I had to make the changes on my OSX machine and am working on getting my Windows machine up. I will run the linter and test script once I have my Windows machine up, but wanted to get your feedback on where I was going for this bug fix. Let me know what you think!

dustinsoftware pushed a commit that referenced this issue Jun 10, 2018
* Added ClientOnly property to ReactComponent

* added conditional to RenderJavascript to decide between ReactDOM.render vs ReactDOM.hydrate

* Added 2 tests to check if correct method ReactDOM.render or ReactDOM.hydrate used when toggling clientOnly parameter in ReactComponent

* Made available ClientOnly and correctly implemented ternary operator using Write

* Removed redundant call to ClientOnly

* Changed tests to correctly take in ClientOnly

* Changed incorrect punctuation in test file

* Corrected tests to use render if true

* Update examples to react 16.4
@dustinsoftware
Copy link
Member

Fixed

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

3 participants