-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(ReactPage): Removing dependency on ReactPage
ReactPage is not the right abstraction for managing the lifecycle of React Native. In theory, React Native can run from a background state (with no pages involved), or can be embedded into a UserControl / ContentControl to run multiple React instances simultaneously. This changeset adds ReactNativeHost to manage the lifecycle of the ReactInstanceManager.
- Loading branch information
Showing
16 changed files
with
390 additions
and
85 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using ReactNative; | ||
using ReactNative.Modules.Core; | ||
using ReactNative.Shell; | ||
using System.Collections.Generic; | ||
|
||
namespace Playground | ||
{ | ||
class MainReactNativeHost : ReactNativeHost | ||
{ | ||
public override string MainComponentName => "Playground"; | ||
|
||
protected override string JavaScriptMainModuleName => "ReactWindows/Playground/index.windows"; | ||
|
||
#if BUNDLE | ||
protected override string JavaScriptBundleFile => "ms-appx:///ReactAssets/index.windows.bundle"; | ||
#endif | ||
|
||
protected override List<IReactPackage> Packages => new List<IReactPackage> | ||
{ | ||
new MainReactPackage(), | ||
}; | ||
|
||
#if !BUNDLE || DEBUG | ||
protected override bool UseDeveloperSupport => true; | ||
#else | ||
protected override bool UseDeveloperSupport => false; | ||
#endif | ||
} | ||
} |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace ReactNative | ||
{ | ||
static class ReactRootViewExtensions | ||
{ | ||
public static void OnCreate(this ReactRootView rootView, ReactNativeHost host) | ||
{ | ||
// TODO: add global keyboard shortcuts | ||
} | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
using ReactNative.Bridge; | ||
using ReactNative.Common; | ||
using ReactNative.Modules.Core; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
|
||
namespace ReactNative | ||
{ | ||
/// <summary> | ||
/// Simple class that holds the <see cref="ReactInstanceManager"/>. | ||
/// </summary> | ||
public abstract class ReactNativeHost : IAsyncDisposable | ||
{ | ||
private ReactInstanceManager _reactInstanceManager; | ||
|
||
/// <summary> | ||
/// Get the current <see cref="ReactInstanceManager"/> instance, or create one. | ||
/// </summary> | ||
public ReactInstanceManager ReactInstanceManager | ||
{ | ||
get | ||
{ | ||
if (_reactInstanceManager == null) | ||
{ | ||
_reactInstanceManager = CreateReactInstanceManager(); | ||
} | ||
|
||
return _reactInstanceManager; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Checks whether this host contains a Re | ||
/// </summary> | ||
public bool HasInstance | ||
{ | ||
get | ||
{ | ||
return _reactInstanceManager != null; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// The main component name. | ||
/// </summary> | ||
public abstract string MainComponentName { get; } | ||
|
||
/// <summary> | ||
/// Instantiates the JavaScript executor. | ||
/// </summary> | ||
protected virtual Func<IJavaScriptExecutor> JavaScriptExecutorFactory | ||
{ | ||
get | ||
{ | ||
return null; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// The name of the main module. | ||
/// </summary> | ||
/// <remarks> | ||
/// Determines the URL to fetch the JavaScript bundle from the packager | ||
/// server. It is only used when dev support is enabled. | ||
/// </remarks> | ||
protected virtual string JavaScriptMainModuleName | ||
{ | ||
get | ||
{ | ||
return "index.windows"; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// The custom path of the bundle file. | ||
/// </summary> | ||
/// <remarks> | ||
/// This is used in cases where the bundle should be loaded from a | ||
/// custom path. | ||
/// </remarks> | ||
protected virtual string JavaScriptBundleFile | ||
{ | ||
get | ||
{ | ||
return null; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Signals whether developer mode should be enabled. | ||
/// </summary> | ||
protected abstract bool UseDeveloperSupport { get; } | ||
|
||
/// <summary> | ||
/// The list of <see cref="IReactPackage"/>s used by the application. | ||
/// </summary> | ||
protected abstract List<IReactPackage> Packages { get; } | ||
|
||
/// <summary> | ||
/// Creates a new root view. | ||
/// </summary> | ||
/// <returns>The root view.</returns> | ||
public virtual ReactRootView CreateRootView() | ||
{ | ||
return new ReactRootView(); | ||
} | ||
|
||
/// <summary> | ||
/// Dispose the current instance and release the reference to it. | ||
/// </summary> | ||
/// <returns> | ||
/// A task to await the dispose operation. | ||
/// </returns> | ||
public async Task DisposeAsync() | ||
{ | ||
if (_reactInstanceManager != null) | ||
{ | ||
await _reactInstanceManager.DisposeAsync(); | ||
_reactInstanceManager = null; | ||
} | ||
} | ||
|
||
private ReactInstanceManager CreateReactInstanceManager() | ||
{ | ||
var builder = new ReactInstanceManagerBuilder | ||
{ | ||
UseDeveloperSupport = UseDeveloperSupport, | ||
InitialLifecycleState = LifecycleState.BeforeCreate, | ||
JavaScriptBundleFile = JavaScriptBundleFile, | ||
JavaScriptMainModuleName = JavaScriptMainModuleName, | ||
JavaScriptExecutorFactory = JavaScriptExecutorFactory, | ||
}; | ||
|
||
builder.Packages.AddRange(Packages); | ||
return builder.Build(); | ||
} | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
ReactWindows/ReactNative.Shared/ReactNativeHostExtensions.cs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using Newtonsoft.Json.Linq; | ||
using System; | ||
|
||
namespace ReactNative | ||
{ | ||
/// <summary> | ||
/// An application delegate for managing the lifecycle events in React Native. | ||
/// </summary> | ||
public static class ReactNativeHostExtensions | ||
{ | ||
/// <summary> | ||
/// Called when the application is first initialized. | ||
/// </summary> | ||
/// <param name="host">The React Native host.</param> | ||
public static ReactRootView OnCreate(this ReactNativeHost host) | ||
{ | ||
return OnCreate(host, null); | ||
} | ||
|
||
/// <summary> | ||
/// Called when the application is first initialized. | ||
/// </summary> | ||
/// <param name="host">The React Native host.</param> | ||
/// <param name="initialProps">The initial props.</param> | ||
public static ReactRootView OnCreate(this ReactNativeHost host, JObject initialProps) | ||
{ | ||
var rootView = host.CreateRootView(); | ||
rootView.OnCreate(host); | ||
rootView.StartReactApplication( | ||
host.ReactInstanceManager, | ||
host.MainComponentName, | ||
initialProps); | ||
return rootView; | ||
} | ||
|
||
/// <summary> | ||
/// Resumes the React instance manager. | ||
/// </summary> | ||
/// <param name="host">The React Native host.</param> | ||
/// <param name="onBackPressed"> | ||
/// The action to take when back is pressed. | ||
/// </param> | ||
public static void OnResume(this ReactNativeHost host, Action onBackPressed) | ||
{ | ||
host.ReactInstanceManager.OnResume(onBackPressed); | ||
} | ||
|
||
/// <summary> | ||
/// Suspends the React instance manager. | ||
/// </summary> | ||
/// <param name="host">The React Native host.</param> | ||
public static void OnSuspend(this ReactNativeHost host) | ||
{ | ||
if (host.HasInstance) | ||
{ | ||
host.ReactInstanceManager.OnSuspend(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Applies the activation arguments. | ||
/// </summary> | ||
/// <param name="host">The React Native host.</param> | ||
/// <param name="arguments">The arguments.</param> | ||
public static void ApplyArguments(this ReactNativeHost host, string arguments) | ||
{ | ||
if (!string.IsNullOrEmpty(arguments) && host.HasInstance) | ||
{ | ||
var args = arguments.Split(','); | ||
|
||
var index = Array.IndexOf(args, "remoteDebugging"); | ||
if (index < 0) | ||
{ | ||
return; | ||
} | ||
|
||
if (args.Length <= index + 1) | ||
{ | ||
throw new ArgumentException("Expected value for remoteDebugging argument.", nameof(arguments)); | ||
} | ||
|
||
bool isRemoteDebuggingEnabled; | ||
if (bool.TryParse(args[index + 1], out isRemoteDebuggingEnabled)) | ||
{ | ||
if (host.HasInstance) | ||
{ | ||
host.ReactInstanceManager.DevSupportManager.IsRemoteDebuggingEnabled = isRemoteDebuggingEnabled; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
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
Oops, something went wrong.