Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds experimental fundamental interface #16049

Merged
merged 4 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"debug-test": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source.js --runInBand",
"test": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source.js",
"test-persistent": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source-persistent.js",
"debug-test-persistent": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source-persistent.js --runInBand",
"test-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.source.js",
"test-prod-build": "yarn test-build-prod",
"test-build": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build.js",
Expand Down
20 changes: 20 additions & 0 deletions packages/react-art/src/ReactARTHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,23 @@ export function unmountEventComponent(
): void {
throw new Error('Not yet implemented.');
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
64 changes: 64 additions & 0 deletions packages/react-dom/src/client/ReactDOMHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import type {DOMContainer} from './ReactDOM';
import type {
ReactDOMEventResponder,
ReactDOMEventComponentInstance,
ReactDOMFundamentalComponentInstance,
} from 'shared/ReactDOMTypes';
import {
addRootEventTypesForComponentInstance,
Expand Down Expand Up @@ -103,6 +104,7 @@ export type NoTimeout = -1;
import {
enableSuspenseServerRenderer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';
import warning from 'shared/warning';

Expand Down Expand Up @@ -882,3 +884,65 @@ export function unmountEventComponent(
unmountEventResponder(eventComponentInstance);
}
}

export function getFundamentalComponentInstance(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): Instance {
if (enableFundamentalAPI) {
const {currentFiber, impl, props, state} = fundamentalInstance;
const instance = impl.getInstance(null, props, state);
precacheFiberNode(currentFiber, instance);
return instance;
}
// Because of the flag above, this gets around the Flow error;
return (null: any);
}

export function mountFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, props, state} = fundamentalInstance;
const onMount = impl.onMount;
if (onMount !== undefined) {
onMount(null, instance, props, state);
}
}
}

export function shouldUpdateFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): boolean {
if (enableFundamentalAPI) {
const {impl, prevProps, props, state} = fundamentalInstance;
const shouldUpdate = impl.shouldUpdate;
if (shouldUpdate !== undefined) {
return shouldUpdate(null, prevProps, props, state);
}
}
return true;
}

export function updateFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const onUpdate = impl.onUpdate;
if (onUpdate !== undefined) {
onUpdate(null, instance, prevProps, props, state);
}
}
}

export function unmountFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, props, state} = fundamentalInstance;
const onUnmount = impl.onUnmount;
if (onUnmount !== undefined) {
onUnmount(null, instance, props, state);
}
}
}
39 changes: 39 additions & 0 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
warnAboutDeprecatedLifecycles,
enableSuspenseServerRenderer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';

import {
Expand All @@ -39,6 +40,7 @@ import {
REACT_LAZY_TYPE,
REACT_MEMO_TYPE,
REACT_EVENT_COMPONENT_TYPE,
REACT_FUNDAMENTAL_TYPE,
} from 'shared/ReactSymbols';

import {
Expand Down Expand Up @@ -1190,6 +1192,43 @@ class ReactDOMServerRenderer {
);
}
// eslint-disable-next-line-no-fallthrough
case REACT_FUNDAMENTAL_TYPE: {
if (enableFundamentalAPI) {
const fundamentalImpl = elementType.impl;
const open = fundamentalImpl.getServerSideString(
null,
nextElement.props,
);
const getServerSideStringClose =
fundamentalImpl.getServerSideStringClose;
const close =
getServerSideStringClose !== undefined
? getServerSideStringClose(null, nextElement.props)
: '';
const nextChildren =
fundamentalImpl.reconcileChildren !== false
? toArray(((nextChild: any): ReactElement).props.children)
: [];
const frame: Frame = {
type: null,
domNamespace: parentNamespace,
children: nextChildren,
childIndex: 0,
context: context,
footer: close,
};
if (__DEV__) {
((frame: any): FrameDev).debugElementStack = [];
}
this.stack.push(frame);
return open;
}
invariant(
false,
'ReactDOMServer does not yet support the fundamental API.',
);
}
// eslint-disable-next-line-no-fallthrough
case REACT_LAZY_TYPE:
invariant(
false,
Expand Down
24 changes: 24 additions & 0 deletions packages/react-native-renderer/src/ReactFabricHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,27 @@ export function unmountEventComponent(
unmountEventResponder(eventComponentInstance);
}
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function cloneFundamentalInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
20 changes: 20 additions & 0 deletions packages/react-native-renderer/src/ReactNativeHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,23 @@ export function unmountEventComponent(
): void {
throw new Error('Not yet implemented.');
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
51 changes: 51 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,57 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
unmountEventComponent(): void {
// NO-OP
},

getFundamentalComponentInstance(fundamentalInstance): Instance {
const {impl, props, state} = fundamentalInstance;
return impl.getInstance(null, props, state);
},

mountFundamentalComponent(fundamentalInstance): void {
const {impl, instance, props, state} = fundamentalInstance;
const onMount = impl.onUpdate;
if (onMount !== undefined) {
onMount(null, instance, props, state);
}
},

shouldUpdateFundamentalComponent(fundamentalInstance): boolean {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const shouldUpdate = impl.shouldUpdate;
if (shouldUpdate !== undefined) {
return shouldUpdate(null, instance, prevProps, props, state);
}
return true;
},

updateFundamentalComponent(fundamentalInstance): void {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const onUpdate = impl.onUpdate;
if (onUpdate !== undefined) {
onUpdate(null, instance, prevProps, props, state);
}
},

unmountFundamentalComponent(fundamentalInstance): void {
const {impl, instance, props, state} = fundamentalInstance;
const onUnmount = impl.onUnmount;
if (onUnmount !== undefined) {
onUnmount(null, instance, props, state);
}
},

cloneFundamentalInstance(fundamentalInstance): Instance {
const instance = fundamentalInstance.instance;
return {
children: [],
text: instance.text,
type: instance.type,
prop: instance.prop,
id: instance.id,
context: instance.context,
hidden: instance.hidden,
};
},
};

const hostConfig = useMutation
Expand Down
36 changes: 34 additions & 2 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
ReactPortal,
RefObject,
ReactEventComponent,
ReactFundamentalComponent,
} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';
import type {WorkTag} from 'shared/ReactWorkTags';
Expand All @@ -26,7 +27,11 @@ import type {ReactEventComponentInstance} from 'shared/ReactTypes';

import invariant from 'shared/invariant';
import warningWithoutStack from 'shared/warningWithoutStack';
import {enableProfilerTimer, enableFlareAPI} from 'shared/ReactFeatureFlags';
import {
enableProfilerTimer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';
import {NoEffect, Placement} from 'shared/ReactSideEffectTags';
import {ConcurrentRoot, BatchedRoot} from 'shared/ReactRootTags';
import {
Expand All @@ -49,6 +54,7 @@ import {
SimpleMemoComponent,
LazyComponent,
EventComponent,
FundamentalComponent,
} from 'shared/ReactWorkTags';
import getComponentName from 'shared/getComponentName';

Expand Down Expand Up @@ -79,6 +85,7 @@ import {
REACT_MEMO_TYPE,
REACT_LAZY_TYPE,
REACT_EVENT_COMPONENT_TYPE,
REACT_FUNDAMENTAL_TYPE,
} from 'shared/ReactSymbols';

let hasBadMapPolyfill;
Expand Down Expand Up @@ -663,6 +670,17 @@ export function createFiberFromTypeAndProps(
);
}
break;
case REACT_FUNDAMENTAL_TYPE:
if (enableFundamentalAPI) {
return createFiberFromFundamental(
type,
pendingProps,
mode,
expirationTime,
key,
);
}
break;
}
}
let info = '';
Expand Down Expand Up @@ -742,7 +760,7 @@ export function createFiberFromFragment(
}

export function createFiberFromEventComponent(
eventComponent: ReactEventComponent<any>,
eventComponent: ReactEventComponent<any, any, any>,
pendingProps: any,
mode: TypeOfMode,
expirationTime: ExpirationTime,
Expand All @@ -755,6 +773,20 @@ export function createFiberFromEventComponent(
return fiber;
}

export function createFiberFromFundamental(
fundamentalComponent: ReactFundamentalComponent<any, any>,
pendingProps: any,
mode: TypeOfMode,
expirationTime: ExpirationTime,
key: null | string,
): Fiber {
const fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
fiber.elementType = fundamentalComponent;
fiber.type = fundamentalComponent;
fiber.expirationTime = expirationTime;
return fiber;
}

function createFiberFromProfiler(
pendingProps: any,
mode: TypeOfMode,
Expand Down
Loading