mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-28 20:25:33 +08:00
Summary: This is the couple of hacks I used after I finished #23802 in order to get fabric working on RNTester. This is inspired from prior work by kmagiera. The goal of this PR is to show others what I’m struggling with, and to eventually merge it sans hacks. - Yarn Install - Uncomment the commented out pods in RNTester's pod file - Open RNTesterPods workspace - Run App - this is only for pods, the non-pod RNTester will no longer work until updated with fabric too. - `SurfaceHostingView` & `SurfaceHostingProxyRootView` both try to start the surface immediately, this leads to a race condition due to the javascript not having loaded yet, the hack here is: 1. Swizzle the `start` method on `RCTFabricSurface` to no-op when called. 2. Add observer for `RCTJavaScriptDidLoadNotification` 3. Call private method `_startAllSurfaces` on `_surfacePresenter` in AppDelegate when we receive `RCTJavaScriptDidLoadNotification`. [General] [Added] - Use Fabric in RNTester Pull Request resolved: https://github.com/facebook/react-native/pull/23803 Reviewed By: shergin, mdvacca Differential Revision: D14450726 Pulled By: fkgozali fbshipit-source-id: 8ae2d48634fecb60db539aaf0a2c89ba1f572c27
195 lines
5.1 KiB
JavaScript
195 lines
5.1 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
* @flow
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
require('InitializeCore');
|
|
const AsyncStorage = require('AsyncStorage');
|
|
const BackHandler = require('BackHandler');
|
|
const Linking = require('Linking');
|
|
const React = require('react');
|
|
const ReactNative = require('react-native');
|
|
const RNTesterActions = require('./RNTesterActions');
|
|
const RNTesterExampleContainer = require('./RNTesterExampleContainer');
|
|
const RNTesterExampleList = require('./RNTesterExampleList');
|
|
const RNTesterList = require('./RNTesterList.ios');
|
|
const RNTesterNavigationReducer = require('./RNTesterNavigationReducer');
|
|
const SnapshotViewIOS = require('./SnapshotViewIOS.ios');
|
|
const URIActionMap = require('./URIActionMap');
|
|
|
|
const {
|
|
Button,
|
|
AppRegistry,
|
|
StyleSheet,
|
|
Text,
|
|
View,
|
|
SafeAreaView,
|
|
YellowBox,
|
|
} = ReactNative;
|
|
|
|
import type {RNTesterExample} from 'RNTesterTypes';
|
|
import type {RNTesterAction} from './RNTesterActions';
|
|
import type {RNTesterNavigationState} from './RNTesterNavigationReducer';
|
|
|
|
type Props = {
|
|
exampleFromAppetizeParams: string,
|
|
};
|
|
|
|
YellowBox.ignoreWarnings([
|
|
'Module RCTImagePickerManager requires main queue setup',
|
|
]);
|
|
|
|
const APP_STATE_KEY = 'RNTesterAppState.v2';
|
|
|
|
const Header = ({onBack, title}: {onBack?: () => mixed, title: string}) => (
|
|
<SafeAreaView style={styles.headerContainer}>
|
|
<View style={styles.header}>
|
|
<View style={styles.headerCenter}>
|
|
<Text style={styles.title}>{title}</Text>
|
|
</View>
|
|
{onBack && (
|
|
<View style={styles.headerLeft}>
|
|
<Button title="Back" onPress={onBack} />
|
|
</View>
|
|
)}
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
|
|
class RNTesterApp extends React.Component<Props, RNTesterNavigationState> {
|
|
UNSAFE_componentWillMount() {
|
|
BackHandler.addEventListener('hardwareBackPress', this._handleBack);
|
|
}
|
|
|
|
componentDidMount() {
|
|
Linking.getInitialURL().then(url => {
|
|
AsyncStorage.getItem(APP_STATE_KEY, (err, storedString) => {
|
|
const exampleAction = URIActionMap(
|
|
this.props.exampleFromAppetizeParams,
|
|
);
|
|
const urlAction = URIActionMap(url);
|
|
const launchAction = exampleAction || urlAction;
|
|
const initialAction = launchAction || {type: 'InitialAction'};
|
|
this.setState(RNTesterNavigationReducer(undefined, initialAction));
|
|
});
|
|
});
|
|
|
|
Linking.addEventListener('url', url => {
|
|
this._handleAction(URIActionMap(url));
|
|
});
|
|
}
|
|
|
|
_handleBack = () => {
|
|
this._handleAction(RNTesterActions.Back());
|
|
};
|
|
|
|
_handleAction = (action: ?RNTesterAction) => {
|
|
if (!action) {
|
|
return;
|
|
}
|
|
const newState = RNTesterNavigationReducer(this.state, action);
|
|
if (this.state !== newState) {
|
|
this.setState(newState, () =>
|
|
AsyncStorage.setItem(APP_STATE_KEY, JSON.stringify(this.state)),
|
|
);
|
|
}
|
|
};
|
|
|
|
render() {
|
|
if (!this.state) {
|
|
return null;
|
|
}
|
|
if (this.state.openExample) {
|
|
const Component = RNTesterList.Modules[this.state.openExample];
|
|
if (Component && Component.external) {
|
|
return <Component onExampleExit={this._handleBack} />;
|
|
} else {
|
|
return (
|
|
<View style={styles.exampleContainer}>
|
|
<Header onBack={this._handleBack} title={Component.title} />
|
|
<RNTesterExampleContainer module={Component} />
|
|
</View>
|
|
);
|
|
}
|
|
}
|
|
return (
|
|
<View style={styles.exampleContainer}>
|
|
<Header title="RNTester" />
|
|
<RNTesterExampleList
|
|
onNavigate={this._handleAction}
|
|
list={RNTesterList}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
headerContainer: {
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
borderBottomColor: '#96969A',
|
|
backgroundColor: '#F5F5F6',
|
|
},
|
|
header: {
|
|
height: 40,
|
|
flexDirection: 'row',
|
|
},
|
|
headerLeft: {},
|
|
headerCenter: {
|
|
flex: 1,
|
|
position: 'absolute',
|
|
top: 7,
|
|
left: 0,
|
|
right: 0,
|
|
alignItems: 'center',
|
|
},
|
|
title: {
|
|
fontSize: 19,
|
|
fontWeight: '600',
|
|
textAlign: 'center',
|
|
},
|
|
exampleContainer: {
|
|
flex: 1,
|
|
},
|
|
});
|
|
|
|
AppRegistry.registerComponent('SetPropertiesExampleApp', () =>
|
|
require('./SetPropertiesExampleApp'),
|
|
);
|
|
AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () =>
|
|
require('./RootViewSizeFlexibilityExampleApp'),
|
|
);
|
|
AppRegistry.registerComponent('RNTesterApp', () => RNTesterApp);
|
|
|
|
// Register suitable examples for snapshot tests
|
|
RNTesterList.ComponentExamples.concat(RNTesterList.APIExamples).forEach(
|
|
(Example: RNTesterExample) => {
|
|
const ExampleModule = Example.module;
|
|
if (ExampleModule.displayName) {
|
|
class Snapshotter extends React.Component<{}> {
|
|
render() {
|
|
return (
|
|
<SnapshotViewIOS>
|
|
<RNTesterExampleContainer module={ExampleModule} />
|
|
</SnapshotViewIOS>
|
|
);
|
|
}
|
|
}
|
|
|
|
AppRegistry.registerComponent(
|
|
ExampleModule.displayName,
|
|
() => Snapshotter,
|
|
);
|
|
}
|
|
},
|
|
);
|
|
|
|
module.exports = RNTesterApp;
|