Skip to content

Commit

Permalink
TM: Added TurboModuleExample in RNTester
Browse files Browse the repository at this point in the history
Summary:
This showcases SampleTurboModule usage in RNTester. Notes:
* iOS only for now, and you must use cocoapods version.
* You cannot use Chrome debugger when loading this specific example.

As illustrated in the example, the callsite should access `NativeSampleTurboModule` to access the native side.

{F155901711}

Reviewed By: cpojer

Differential Revision: D14932537

fbshipit-source-id: a733e1cd3b642b9e572d5ac6347f4775d495578a
  • Loading branch information
fkgozali authored and facebook-github-bot committed Apr 15, 2019
1 parent 4da6e4a commit 0bd931e
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Libraries/react-native/react-native-implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ module.exports = {
get ToastAndroid() {
return require('ToastAndroid');
},
get TurboModuleRegistry() {
return require('TurboModuleRegistry');
},
get TVEventHandler() {
return require('TVEventHandler');
},
Expand Down
5 changes: 5 additions & 0 deletions RNTester/js/RNTesterList.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ const APIExamples: Array<RNTesterExample> = [
module: require('./TransformExample'),
supportsTVOS: true,
},
{
key: 'TurboModuleExample',
module: require('./TurboModuleExample'),
supportsTVOS: false,
},
{
key: 'TVEventHandlerExample',
module: require('./TVEventHandlerExample'),
Expand Down
177 changes: 177 additions & 0 deletions RNTester/js/SampleTurboModuleExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/**
* 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';

import NativeSampleTurboModule from 'NativeSampleTurboModule';
import {
StyleSheet,
Text,
View,
FlatList,
Platform,
TouchableOpacity,
} from 'react-native';
import * as React from 'react';

type State = {|
testResults: {[string]: {type: string, value: mixed}},
|};

class SampleTurboModuleExample extends React.Component<{||}, State> {
state: State = {
testResults: {},
};

// Add calls to methods in TurboModule here
_tests = {
callback: () =>
NativeSampleTurboModule.getValueWithCallback(callbackValue =>
this._setResult('callback', callbackValue),
),
promise: () =>
NativeSampleTurboModule.getValueWithPromise(false).then(valuePromise =>
this._setResult('promise', valuePromise),
),
rejectPromise: () =>
NativeSampleTurboModule.getValueWithPromise(true)
.then(() => {})
.catch(e => this._setResult('rejectPromise', e.message)),
getConstants: () => NativeSampleTurboModule.getConstants(),
voidFunc: () => NativeSampleTurboModule.voidFunc(),
getBool: () => NativeSampleTurboModule.getBool(true),
getNumber: () => NativeSampleTurboModule.getNumber(99.95),
getString: () => NativeSampleTurboModule.getString('Hello'),
getArray: () =>
NativeSampleTurboModule.getArray([
{a: 1, b: 'foo'},
{a: 2, b: 'bar'},
null,
]),
getObject: () =>
NativeSampleTurboModule.getObject({a: 1, b: 'foo', c: null}),
getValue: () =>
NativeSampleTurboModule.getValue(5, 'test', {a: 1, b: 'foo'}),
};

_setResult(name, result) {
this.setState(({testResults}) => ({
testResults: {
...testResults,
[name]: {value: result, type: typeof result},
},
}));
}

_renderResult(name) {
const result = this.state.testResults[name] || {};
return (
<View style={styles.result}>
<Text style={[styles.value]}>{JSON.stringify(result.value)}</Text>
<Text style={[styles.type]}>{result.type}</Text>
</View>
);
}

componentDidMount() {
if (global.__turboModuleProxy == null) {
throw new Error(
'Cannot load this example because TurboModule is not configured.',
);
}
if (Platform.OS === 'ios') {
// iOS is fully implemented, so show all results immediately.
Object.keys(this._tests).forEach(item =>
this._setResult(item, this._tests[item]()),
);
}
}

render(): React.Node {
return (
<View style={styles.container}>
<View style={styles.item}>
<TouchableOpacity
style={[styles.column, styles.button]}
onPress={() =>
Object.keys(this._tests).forEach(item =>
this._setResult(item, this._tests[item]()),
)
}>
<Text style={styles.buttonTextLarge}>Run all tests</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({testResults: {}})}
style={[styles.column, styles.button]}>
<Text style={styles.buttonTextLarge}>Clear results</Text>
</TouchableOpacity>
</View>
<FlatList
data={Object.keys(this._tests)}
keyExtractor={item => item}
renderItem={({item}) => (
<View style={styles.item}>
<TouchableOpacity
style={[styles.column, styles.button]}
onPress={e => this._setResult(item, this._tests[item]())}>
<Text style={styles.buttonText}>{item}</Text>
</TouchableOpacity>
<View style={[styles.column]}>{this._renderResult(item)}</View>
</View>
)}
/>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
flexDirection: 'row',
margin: 6,
},
column: {
flex: 2,
justifyContent: 'center',
padding: 3,
},
result: {
alignItems: 'stretch',
justifyContent: 'space-between',
},
value: {
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
fontSize: 12,
},
type: {
color: '#333',
fontSize: 10,
},
button: {
borderColor: '#444',
padding: 3,
flex: 1,
},
buttonTextLarge: {
textAlign: 'center',
color: 'rgb(0,122,255)',
fontSize: 16,
padding: 6,
},
buttonText: {
color: 'rgb(0,122,255)',
textAlign: 'center',
},
});

module.exports = SampleTurboModuleExample;
26 changes: 26 additions & 0 deletions RNTester/js/TurboModuleExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* 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';

const React = require('react');
const SampleTurboModuleExample = require('SampleTurboModuleExample');

exports.displayName = (undefined: ?string);
exports.title = 'TurboModule';
exports.description = 'Usage of TurboModule';
exports.examples = [
{
title: 'SampleTurboModule',
render: function(): React.Element<any> {
return <SampleTurboModuleExample />;
},
},
];

1 comment on commit 0bd931e

@fkgozali
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simulator Screen Shot - iPhone Xʀ - 2019-04-15 at 00 47 21

Please sign in to comment.