Last active
September 26, 2023 23:20
-
-
Save mootinator/b8eae6f8f2e32415802826172f0de10a to your computer and use it in GitHub Desktop.
React.NET React 18 Shim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using React; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Text; | |
namespace React18Shim | |
{ | |
public class React18Component : ReactComponent | |
{ | |
public React18Component(IReactEnvironment environment, IReactSiteConfiguration configuration, IReactIdGenerator reactIdGenerator, string componentName, string containerId) : base(environment, configuration, reactIdGenerator, componentName, containerId) | |
{ | |
} | |
/// <summary> | |
/// Renders the JavaScript required to initialise this component client-side. This will | |
/// initialise the React component, which includes attach event handlers to the | |
/// server-rendered HTML. | |
/// </summary> | |
/// <param name="writer">The <see cref="T:System.IO.TextWriter" /> to which the content is written</param> | |
/// <param name="waitForDOMContentLoad">Delays the component init until the page load event fires. Useful if the component script tags are located after the call to Html.ReactWithInit. </param> | |
/// <returns>JavaScript</returns> | |
public override void RenderJavaScript(TextWriter writer, bool waitForDOMContentLoad) | |
{ | |
if (waitForDOMContentLoad) | |
{ | |
writer.Write("window.addEventListener('DOMContentLoaded', function() {"); | |
} | |
var hydrate = _configuration.UseServerSideRendering && !ClientOnly; | |
writer.Write( | |
!hydrate ? "ReactDOM.createRoot(" : "ReactDOM.hydrateRoot("); | |
writer.Write("document.getElementById(\""); | |
writer.Write(ContainerId); | |
if (hydrate) | |
{ | |
writer.Write("\")"); | |
writer.Write(", "); | |
WriteComponentInitialiser(writer); | |
writer.Write(")"); | |
} else | |
{ | |
writer.Write("\"))"); | |
writer.Write(".render("); | |
WriteComponentInitialiser(writer); | |
writer.Write(")"); | |
} | |
if (waitForDOMContentLoad) | |
{ | |
writer.Write("});"); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using React; | |
using System; | |
namespace React18Shim | |
{ | |
public class React18Environment : ReactEnvironment | |
{ | |
private readonly IReactIdGenerator _reactIdGenerator; | |
public React18Environment(IJavaScriptEngineFactory engineFactory, IReactSiteConfiguration config, ICache cache, IFileSystem fileSystem, IFileCacheHash fileCacheHash, IReactIdGenerator reactIdGenerator) : base(engineFactory, config, cache, fileSystem, fileCacheHash, reactIdGenerator) | |
{ | |
_reactIdGenerator = reactIdGenerator; | |
} | |
/// <summary> | |
/// Creates an instance of the specified React JavaScript component. | |
/// </summary> | |
/// <typeparam name="T">Type of the props</typeparam> | |
/// <param name="componentName">Name of the component</param> | |
/// <param name="props">Props to use</param> | |
/// <param name="containerId">ID to use for the container HTML tag. Defaults to an auto-generated ID</param> | |
/// <param name="clientOnly">True if server-side rendering will be bypassed. Defaults to false.</param> | |
/// <param name="serverOnly">True if this component only should be rendered server-side. Defaults to false.</param> | |
/// <param name="skipLazyInit">Skip adding to components list, which is used during GetInitJavascript</param> | |
/// <returns>The component</returns> | |
public override IReactComponent CreateComponent<T>(string componentName, T props, string containerId = null, bool clientOnly = false, bool serverOnly = false, bool skipLazyInit = false) | |
{ | |
if (!clientOnly) | |
{ | |
EnsureUserScriptsLoaded(); | |
} | |
var component = new React18Component(this, _config, _reactIdGenerator, componentName, containerId) | |
{ | |
ClientOnly = clientOnly, | |
Props = props, | |
ServerOnly = serverOnly | |
}; | |
if (!skipLazyInit) | |
{ | |
_components.Add(component); | |
} | |
return component; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
services.AddReact(); | |
services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName).AddChakraCore(); | |
... | |
app.UseReact(config => | |
{ | |
config | |
// .DisableServerSideRendering() | |
.SetLoadBabel(false) | |
.SetLoadReact(false) | |
.AddScriptWithoutTransform("~/js/polyfills.js") | |
.AddScriptWithoutTransform("~/js/server.js"); | |
}); | |
var wasregistered = React.AssemblyRegistration.Container.Unregister<IReactEnvironment>(); | |
React.AssemblyRegistration.Container.Register<IReactEnvironment, React18Environment>().AsPerRequestSingleton(); | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment