Skip to content

Commit

Permalink
Merge pull request #17 from fortedigital/feature/ssr-only
Browse files Browse the repository at this point in the history
Added rendering mode setting for component
  • Loading branch information
AyronK authored May 18, 2023
2 parents a1895b6 + 65f0caa commit db13b55
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Forte.React.AspNetCore/Forte.React.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<Packable>true</Packable>
<VersionPrefix>0.2.0.0</VersionPrefix>
<VersionPrefix>0.2.1.0</VersionPrefix>
</PropertyGroup>

<PropertyGroup>
Expand Down
8 changes: 4 additions & 4 deletions Forte.React.AspNetCore/HtmlHelperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public static IHtmlString React<T>(this HtmlHelper _, string componentName, T pr
public static IHtmlString React<TComponent>(this HtmlHelper _, TComponent component) where TComponent : IReactComponent
{
var reactService = DependencyResolver.Current.GetService<IReactService>();
var renderedComponent = reactService.RenderToStringAsync(component.Path, null, component.ClientOnly).GetAwaiter().GetResult();
var renderedComponent = reactService.RenderToStringAsync(component.Path, null, component.RenderingMode).GetAwaiter().GetResult();

return new HtmlString(renderedComponent);
}

public static IHtmlString React<TComponent, TProps>(this HtmlHelper _, TComponent component) where TComponent : IReactComponent<TProps> where TProps : IReactComponentProps
{
var reactService = DependencyResolver.Current.GetService<IReactService>();
var renderedComponent = reactService.RenderToStringAsync(component.Path, component.Props, component.ClientOnly).GetAwaiter().GetResult();
var renderedComponent = reactService.RenderToStringAsync(component.Path, component.Props, component.RenderingMode).GetAwaiter().GetResult();

return new HtmlString(renderedComponent);
}
Expand All @@ -61,14 +61,14 @@ public static async Task<IHtmlContent> ReactAsync<TComponent>(this IHtmlHelper h
{
var reactService = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IReactService>();

return new HtmlString(await reactService.RenderToStringAsync(component.Path, null, component.ClientOnly));
return new HtmlString(await reactService.RenderToStringAsync(component.Path, null, component.RenderingMode));
}

public static async Task<IHtmlContent> ReactAsync<TComponent, TProps>(this IHtmlHelper htmlHelper, TComponent component) where TComponent : IReactComponent<TProps> where TProps : IReactComponentProps
{
var reactService = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IReactService>();

return new HtmlString(await reactService.RenderToStringAsync(component.Path, component.Props, component.ClientOnly));
return new HtmlString(await reactService.RenderToStringAsync(component.Path, component.Props, component.RenderingMode));
}

public static IHtmlContent InitJavascript(this IHtmlHelper htmlHelper)
Expand Down
6 changes: 3 additions & 3 deletions Forte.React.AspNetCore/React/Component.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ internal class Component : IReactComponent
public object? Props { get; }
public string ContainerId { get; }
public string JsonContainerId { get; }
public bool ClientOnly { get; }
public RenderingMode RenderingMode { get; }

public Component(string path, object? props = null, bool clientOnly = false)
public Component(string path, object? props = null, RenderingMode renderingMode = RenderingMode.ClientAndServer)
{
Path = path;
Props = props;
ClientOnly = clientOnly;
RenderingMode = renderingMode;
ContainerId = Guid.NewGuid().ToString("n").Substring(0, 8);
JsonContainerId = ContainerId + "-json";
}
Expand Down
2 changes: 1 addition & 1 deletion Forte.React.AspNetCore/React/IReactComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ public interface IReactComponent<out TProps> : IReactComponent where TProps : IR
public interface IReactComponent
{
string Path { get; }
bool ClientOnly { get; }
RenderingMode RenderingMode { get; }
}
27 changes: 14 additions & 13 deletions Forte.React.AspNetCore/React/ReactService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Forte.React.AspNetCore.React;

public interface IReactService
{
Task<string> RenderToStringAsync(string componentName, object? props = null, bool clientOnly = false);
Task<string> RenderToStringAsync(string componentName, object? props = null, RenderingMode renderingMode = RenderingMode.ClientAndServer);

Task WriteOutputHtmlToAsync(TextWriter writer, string componentName, object? props = null,
WriteOutputHtmlToOptions? writeOutputHtmlToOptions = null);
Expand Down Expand Up @@ -106,12 +106,12 @@ Stream ModuleFactory()
return result!;
}

public async Task<string> RenderToStringAsync(string componentName, object? props = null, bool clientOnly = false)
public async Task<string> RenderToStringAsync(string componentName, object? props = null, RenderingMode renderingMode = RenderingMode.ClientAndServer)
{
var component = new Component(componentName, props, clientOnly);
var component = new Component(componentName, props, renderingMode);
Components.Add(component);

if (_config.IsServerSideDisabled || clientOnly)
if (_config.IsServerSideDisabled || renderingMode == RenderingMode.Client)
{
return WrapRenderedStringComponent(string.Empty, component);
}
Expand Down Expand Up @@ -162,19 +162,20 @@ private static string WrapRenderedStringComponent(string? renderedStringComponen

public string GetInitJavascript()
{
string InitFunction(Component c)
{
var shouldHydrate = !_config.IsServerSideDisabled && !c.ClientOnly;
return shouldHydrate ? Hydrate(c) : Render(c);
}

var componentInitiation = Components.Select(InitFunction);
var componentInitiation = Components.Where(IsInitRequired).Select(GetInitJavascriptSource);

return $"<script>{string.Join("", componentInitiation)}</script>";
}

private static string GetElementById(string containerId)
=> $"document.getElementById(\"{containerId}\")";
private string GetInitJavascriptSource(Component c)
{
var shouldHydrate = !_config.IsServerSideDisabled && c.RenderingMode.HasFlag(RenderingMode.Server);
return shouldHydrate ? Hydrate(c) : Render(c);
}

private static bool IsInitRequired(Component c) => c.RenderingMode.HasFlag(RenderingMode.Client);

private static string GetElementById(string containerId) => $"document.getElementById(\"{containerId}\")";

private string CreateElement(Component component)
{
Expand Down
22 changes: 22 additions & 0 deletions Forte.React.AspNetCore/React/RenderingMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;

namespace Forte.React.AspNetCore.React;

[Flags]
public enum RenderingMode
{
/// <summary>
/// Component will only be rendered on the client.
/// </summary>
Client = 0,

/// <summary>
/// Component will only be rendered as static markup on the server without hydration on the client.
/// </summary>
Server = 1,

/// <summary>
/// Component will be rendered on the server and hydrated on the client.
/// </summary>
ClientAndServer = Client | Server,
}

0 comments on commit db13b55

Please sign in to comment.