Skip to content

Commit 131aca8

Browse files
kpkozakdustinsoftware
authored andcommitted
Fix error calling hydrate instead of render when SSR disabled (#636)
This commit fixes #632
1 parent 6a56cef commit 131aca8

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/React.Core/ReactComponent.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ public virtual string RenderJavaScript()
245245
/// <returns>JavaScript</returns>
246246
public virtual void RenderJavaScript(TextWriter writer)
247247
{
248-
writer.Write(ClientOnly ? "ReactDOM.render(" : "ReactDOM.hydrate(");
248+
writer.Write(
249+
!_configuration.UseServerSideRendering || ClientOnly ? "ReactDOM.render(" : "ReactDOM.hydrate(");
249250
WriteComponentInitialiser(writer);
250251
writer.Write(", document.getElementById(\"");
251252
writer.Write(ContainerId);

tests/React.Tests/Core/ReactComponentTest.cs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void RenderHtmlShouldThrowExceptionIfComponentDoesNotExist()
2121
{
2222
var environment = new Mock<IReactEnvironment>();
2323
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(false);
24-
var config = new Mock<IReactSiteConfiguration>();
24+
var config = CreateDefaultConfigMock();
2525
config.Setup(x => x.UseServerSideRendering).Returns(true);
2626
var reactIdGenerator = new Mock<IReactIdGenerator>();
2727

@@ -38,7 +38,7 @@ public void RenderHtmlShouldCallRenderComponent()
3838
{
3939
var environment = new Mock<IReactEnvironment>();
4040
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
41-
var config = new Mock<IReactSiteConfiguration>();
41+
var config = CreateDefaultConfigMock();
4242
config.Setup(x => x.UseServerSideRendering).Returns(true);
4343
var reactIdGenerator = new Mock<IReactIdGenerator>();
4444

@@ -58,7 +58,7 @@ public void RenderHtmlShouldWrapComponentInDiv()
5858
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
5959
environment.Setup(x => x.Execute<string>(@"ReactDOMServer.renderToString(React.createElement(Foo, {""hello"":""World""}))"))
6060
.Returns("[HTML]");
61-
var config = new Mock<IReactSiteConfiguration>();
61+
var config = CreateDefaultConfigMock();
6262
config.Setup(x => x.UseServerSideRendering).Returns(true);
6363
var reactIdGenerator = new Mock<IReactIdGenerator>();
6464

@@ -78,7 +78,7 @@ public void RenderHtmlShouldNotRenderComponentHtml()
7878
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
7979
environment.Setup(x => x.Execute<string>(@"React.renderToString(React.createElement(Foo, {""hello"":""World""}))"))
8080
.Returns("[HTML]");
81-
var config = new Mock<IReactSiteConfiguration>();
81+
var config = CreateDefaultConfigMock();
8282
var reactIdGenerator = new Mock<IReactIdGenerator>();
8383

8484
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
@@ -96,7 +96,7 @@ public void RenderHtmlShouldNotRenderClientSideAttributes()
9696
{
9797
var environment = new Mock<IReactEnvironment>();
9898
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
99-
var config = new Mock<IReactSiteConfiguration>();
99+
var config = CreateDefaultConfigMock();
100100
config.Setup(x => x.UseServerSideRendering).Returns(true);
101101
var reactIdGenerator = new Mock<IReactIdGenerator>();
102102

@@ -112,7 +112,7 @@ public void RenderHtmlShouldNotRenderClientSideAttributes()
112112
[Fact]
113113
public void RenderHtmlShouldWrapComponentInCustomElement()
114114
{
115-
var config = new Mock<IReactSiteConfiguration>();
115+
var config = CreateDefaultConfigMock();
116116
config.Setup(x => x.UseServerSideRendering).Returns(true);
117117
var environment = new Mock<IReactEnvironment>();
118118
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
@@ -133,7 +133,7 @@ public void RenderHtmlShouldWrapComponentInCustomElement()
133133
[Fact]
134134
public void RenderHtmlShouldNotRenderComponentWhenContainerOnly()
135135
{
136-
var config = new Mock<IReactSiteConfiguration>();
136+
var config = CreateDefaultConfigMock();
137137
config.Setup(x => x.UseServerSideRendering).Returns(true);
138138
var environment = new Mock<IReactEnvironment>();
139139
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
@@ -154,7 +154,7 @@ public void RenderHtmlShouldNotRenderComponentWhenContainerOnly()
154154
[Fact]
155155
public void RenderHtmlShouldNotWrapComponentWhenServerSideOnly()
156156
{
157-
var config = new Mock<IReactSiteConfiguration>();
157+
var config = CreateDefaultConfigMock();
158158
config.Setup(x => x.UseServerSideRendering).Returns(true);
159159
var environment = new Mock<IReactEnvironment>();
160160
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
@@ -174,7 +174,7 @@ public void RenderHtmlShouldNotWrapComponentWhenServerSideOnly()
174174
[Fact]
175175
public void RenderHtmlShouldAddClassToElement()
176176
{
177-
var config = new Mock<IReactSiteConfiguration>();
177+
var config = CreateDefaultConfigMock();
178178
config.Setup(x => x.UseServerSideRendering).Returns(true);
179179
var environment = new Mock<IReactEnvironment>();
180180
environment.Setup(x => x.Execute<bool>("typeof Foo !== 'undefined'")).Returns(true);
@@ -197,7 +197,7 @@ public void RenderHtmlShouldAddClassToElement()
197197
public void RenderJavaScriptShouldCallRenderComponent()
198198
{
199199
var environment = new Mock<IReactEnvironment>();
200-
var config = new Mock<IReactSiteConfiguration>();
200+
var config = CreateDefaultConfigMock();
201201
var reactIdGenerator = new Mock<IReactIdGenerator>();
202202

203203
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
@@ -216,7 +216,7 @@ public void RenderJavaScriptShouldCallRenderComponent()
216216
public void RenderJavaScriptShouldCallRenderComponentWithReactDOMRender()
217217
{
218218
var environment = new Mock<IReactEnvironment>();
219-
var config = new Mock<IReactSiteConfiguration>();
219+
var config = CreateDefaultConfigMock();
220220
var reactIdGenerator = new Mock<IReactIdGenerator>();
221221

222222
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
@@ -236,7 +236,7 @@ public void RenderJavaScriptShouldCallRenderComponentWithReactDOMRender()
236236
public void RenderJavaScriptShouldCallRenderComponentwithReactDOMHydrate()
237237
{
238238
var environment = new Mock<IReactEnvironment>();
239-
var config = new Mock<IReactSiteConfiguration>();
239+
var config = CreateDefaultConfigMock();
240240
var reactIdGenerator = new Mock<IReactIdGenerator>();
241241

242242
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
@@ -252,6 +252,27 @@ public void RenderJavaScriptShouldCallRenderComponentwithReactDOMHydrate()
252252
);
253253
}
254254

255+
[Fact]
256+
public void RenderJavaScriptShouldCallRenderComponentWithReactDomRenderWhenSsrDisabled()
257+
{
258+
var environment = new Mock<IReactEnvironment>();
259+
var config = CreateDefaultConfigMock();
260+
config.SetupGet(x => x.UseServerSideRendering).Returns(false);
261+
262+
var reactIdGenerator = new Mock<IReactIdGenerator>();
263+
var component = new ReactComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container")
264+
{
265+
ClientOnly = false,
266+
Props = new {hello = "World"}
267+
};
268+
var result = component.RenderJavaScript();
269+
270+
Assert.Equal(
271+
@"ReactDOM.render(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))",
272+
result
273+
);
274+
}
275+
255276
[Theory]
256277
[InlineData("Foo", true)]
257278
[InlineData("Foo.Bar", true)]
@@ -278,7 +299,7 @@ public void TestEnsureComponentNameValid(string input, bool expected)
278299
public void GeneratesContainerIdIfNotProvided()
279300
{
280301
var environment = new Mock<IReactEnvironment>();
281-
var config = new Mock<IReactSiteConfiguration>();
302+
var config = CreateDefaultConfigMock();
282303
var reactIdGenerator = new Mock<IReactIdGenerator>();
283304
reactIdGenerator.Setup(x => x.Generate()).Returns("customReactId");
284305

@@ -294,7 +315,7 @@ public void ExceptionThrownIsHandled()
294315
environment.Setup(x => x.Execute<string>(@"ReactDOMServer.renderToString(React.createElement(Foo, {""hello"":""World""}))"))
295316
.Throws(new JsRuntimeException("'undefined' is not an object"));
296317

297-
var config = new Mock<IReactSiteConfiguration>();
318+
var config = CreateDefaultConfigMock();
298319
config.Setup(x => x.UseServerSideRendering).Returns(true);
299320
config.Setup(x => x.ExceptionHandler).Returns(() => throw new ReactServerRenderingException("test"));
300321

@@ -347,7 +368,7 @@ public void RenderFunctionsCalled()
347368
environment.Setup(x => x.Execute<string>(@"postrender();"))
348369
.Returns("postrender-result");
349370

350-
var config = new Mock<IReactSiteConfiguration>();
371+
var config = CreateDefaultConfigMock();
351372
config.Setup(x => x.UseServerSideRendering).Returns(true);
352373
var reactIdGenerator = new Mock<IReactIdGenerator>();
353374

@@ -386,6 +407,13 @@ public void ChainedRenderFunctionsCalled()
386407
Assert.Equal("postrender-result", firstInstance.PostRenderResult);
387408
Assert.Equal("postrender-result", secondInstance.PostRenderResult);
388409
}
410+
411+
private static Mock<IReactSiteConfiguration> CreateDefaultConfigMock()
412+
{
413+
var configMock = new Mock<IReactSiteConfiguration>();
414+
configMock.SetupGet(x => x.UseServerSideRendering).Returns(true);
415+
return configMock;
416+
}
389417

390418
private sealed class TestRenderFunctions : RenderFunctionsBase
391419
{

0 commit comments

Comments
 (0)