UNPKG

react-nativescript

Version:
128 lines 6.47 kB
import { Application, } from "@nativescript/core"; import { __unstable__forwardNavOpts } from "./nativescript-vue-next/runtime/navigation"; export { __unstable__forwardNavOpts }; import { LegacyRoot } from "react-reconciler/constants"; import * as console from "./shared/Logger"; import { reactReconcilerInst } from "./client/HostConfig"; import { createPortal as _createPortal } from "./client/ReactPortal"; import { NSVRoot, NSVElement, NSVNode, NSVComment, NSVText, } from "./nativescript-vue-next/runtime/nodes"; import { markContainerAsRoot } from "./client/ComponentTree"; export { NSVRoot, NSVElement, NSVNode, NSVComment, NSVText }; const { version: ReactNativeScriptVersion } = require("../package.json"); export { registerElement } from "./nativescript-vue-next/runtime/registry"; export { ListView } from "./components/ListView"; export { StyleSheet } from "./client/StyleSheet"; // declare global { // var __DEV__: boolean|undefined; // } // declare let __DEV__: boolean|undefined; // https://blog.atulr.com/react-custom-renderer-1/ export function createPortal(children, // ReactFabric passes in a containerTag rather than a container; hope it can figure out how to re-use a root when the container is null :/ container, key = null) { // invariant( // isValidContainer(container), // 'Target container is not a DOM element.', // ); // TODO (from Facebook): pass ReactDOM portal implementation as third argument const portal = _createPortal(children, container, null, key); // console.log(`Created portal:`, portal); return portal; } const roots = new Map(); const defaultOnRecoverableError = typeof reportError === "function" ? // In modern browsers, reportError will dispatch an error event, // emulating an uncaught JavaScript error. reportError : (error) => { // In older browsers and test environments, fallback to console.error. // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args console.error(error); }; /** * React NativeScript can render into any container that extends View, * but it makes sense to use the Frame > Page model if your whole app * (rather than a portion of it) will be described using React NativeScript. * * @param reactElement - Your <App/> component. * @param domElement - Your root component; typically Page, but can be any View. Accepts null for a detached tree. * @param callback - A callback to run after the component (typically <App/>) is rendered. * @param containerTag - A unique key by which to keep track of the root (useful when the domElement is null). * 'roots' with reference to: https://github.com/facebook/react/blob/ef4ac42f8893afd0240d2679db7438f1b599bbd4/packages/react-native-renderer/src/ReactFabric.js#L119 * @returns a ref to the container. */ export function render(reactElement, domElement, callback = () => undefined, containerTag = null, strictMode) { const key = containerTag || domElement; let root = roots.get(key); if (!root) { const hydrationCallbacks = null; const identifierPrefix = ""; const concurrentUpdatesByDefaultOverride = null; const onRecoverableError = defaultOnRecoverableError; const transitionCallbacks = null; root = reactReconcilerInst.createContainer(domElement, // TODO: Update to ConcurrentRoot LegacyRoot, hydrationCallbacks, !!strictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks); markContainerAsRoot(root.current, domElement); roots.set(key, root); } reactReconcilerInst.updateContainer(reactElement, root, null, callback); return reactReconcilerInst.getPublicRootInstance(root); } // https://github.com/facebook/react/blob/61f62246c8cfb76a4a19d1661eeaa5822ec37b36/packages/react-native-renderer/src/ReactNativeRenderer.js#L139 /** * Calls removeChildFromContainer() to make the container remove its immediate child. * If said container is null (i.e. a detached tree), note that null.removeChild() doesn't exist, so it's a no-op. * Either way, it'll delete our reference to the root and thus should remove the React association from it. * @param containerTag - the key uniquely identifying this root (either the container itself, or a string). */ export function unmountComponentAtNode(containerTag) { const root = roots.get(containerTag); if (!root) return; // TODO (from FB): Is it safe to reset this now or should I wait since this unmount could be deferred? reactReconcilerInst.updateContainer(null, root, null, () => { roots.delete(containerTag); }); } /* * https://github.com/reduxjs/react-redux/issues/1392 * https://github.com/facebook/react/blob/b15bf36750ca4c4a5a09f2de76c5315ded1258d0/packages/react-native-renderer/src/ReactNativeRenderer.js#L230 */ export const unstable_batchedUpdates = reactReconcilerInst.batchedUpdates; /** * Convenience function to start your React NativeScript app. * This should be placed as the final line of your app.ts file, as no * code will run after it (at least on iOS). * * @param app - Your <App/> component. */ export function start(app) { const existingRootView = Application.getRootView(); const _hasLaunched = Application.hasLaunched(); console.log(`[ReactNativeScript.ts] start(). hasLaunched(): ${_hasLaunched} existing rootView was: ${existingRootView}`); if (_hasLaunched || existingRootView) { console.log(`[ReactNativeScript.ts] start() called again - hot reload, so shall no-op`); /* As typings say, indeed reloadPage() doesn't exist. Maybe it's just a Vue thing. */ // if(existingRootView instanceof Frame){ // console.log(`[renderIntoRootView] hot reload: calling reloadPage() on root frame`); // if(existingRootView.currentPage){ // (existingRootView as any).reloadPage(); // } // } return; } reactReconcilerInst.injectIntoDevTools({ bundleType: __DEV__ ? 1 : 0, rendererPackageName: "react-nativescript", version: ReactNativeScriptVersion, }); Application.run({ create: () => { const root = new NSVRoot(); render(app, root, () => console.log(`Container updated!`), "__APP_ROOT__"); return root.baseRef.nativeView; }, }); } //# sourceMappingURL=index.js.map