React Native custom components

50
1 React-Native custom components

Transcript of React Native custom components

Page 1: React Native custom components

1

React-Nativecustom

components

Page 2: React Native custom components

2

Who are you?

Page 3: React Native custom components

3

Jeremy Grancher� Front-end developer since 4 years� iOS developer for a year ¯\_(ツ)_/¯� Enjoying work at � Loving kittens and Game of Thrones

Holler

http://twitter.com/jgrancher

http://github.com/jgrancher

Page 4: React Native custom components

4

What are you talking about?

The current state of the React-Native componentsThe need of creating a native componentHow to do itLessons learned from creating react-native-sketch

Page 5: React Native custom components

5

The {this.state.components}Good pun, eh?

Page 6: React Native custom components

6

 The growthRapid adoption...

Pull requests / month over the year

Page 7: React Native custom components

7

 The growth...and still ongoing

The spread doesn't slow down

Page 8: React Native custom components

8

 The growthThe core components are awesome...

ActivityIndicatorIOSDatePickerIOSDrawerLayoutAndroidImageListViewMapViewModalNavigatorNavigatorIOSPickerIOSPickerProgressBarAndroidProgressViewIOSRefreshControlScrollViewSegmentedControlIOS

SliderSliderIOSStatusBarSwitchTabBarIOSTabBarIOS.ItemTextTextInputToolbarAndroidTouchableHighlightTouchableNativeFeedbackTouchableOpacityTouchableWithoutFeedbackViewViewPagerAndroidWebView

Page 9: React Native custom components

9

 The Growth...and still evolving

(╯°□°)╯︵ ┻━┻)

Page 11: React Native custom components

11

 The Growth

RNPM though. �

Page 12: React Native custom components

12

 The Growth

Experimental swipeable list view?

Capture from react-native-swipeable

Page 13: React Native custom components

13

So, I get your point.React-Native by itself is great.

� Solid built-in components list� Overwhelming community⚡ Moves and evolves quickly� Prioritized features requests in Product Pain

Page 14: React Native custom components

14

But you might need more.

Page 15: React Native custom components

15

 The expansionSome important components have been built by the community...

<Camera /> component by Loch Wansbrough - ★1130

Page 16: React Native custom components

16

 The expansionSome important components have been built by the community...

<Maps /> component by Leland Richardson - ★912

Page 17: React Native custom components

17

 The expansionSome important components have been built by the community...

<Video /> component by Brent Vatne - ★689

Page 18: React Native custom components

18

 The expansionSome important components have been built by the community... var RNFS = require('react-native-fs');

// Create a path you want to write to var path = RNFS.DocumentDirectoryPath + '/test.txt';

// Write the file RNFS.writeFile(path, 'Hello React-Native Sydney!', 'utf8') .then((success) => console.log('Valar Morghulis!')) .catch((err) => console.log('You know nothing.', err.message));

A �le-system access by Johannes Lumpe - ★349

Page 19: React Native custom components

19

 The expansion...and will stay that way.

¯\_(ツ)_/¯

Page 20: React Native custom components

20

So, when will you needa custom component?

Page 21: React Native custom components

21

 The customisationWhen you need a wrapper not found in...

The core components (UIKit classes: View, Button, TabBar...)The community components (Camera, Maps, ActionSheet,FileSystem...)

Bad luck. You'll have to build that logic in Objective-C / Java yourself...

Page 22: React Native custom components

22

Nooooooo

Catelyn Stark didn't know anything about iOS development.

Page 23: React Native custom components

23

 The customisation... or...

You have built a native iOS / Android component that you want touse in JS without reimplementing the logic.

Lucky you. Because react-native will let you create a bridge for it.

Page 24: React Native custom components

24

Page 25: React Native custom components

25

 The customisation

A native component can be...

A "utility" that plays with the platform API (ie. FileSystem)A "UI component" that renders a native view along with it (ie. Maps)

Page 26: React Native custom components

26

How to create a customcomponent?

Page 27: React Native custom components

27

DEMO

Page 28: React Native custom components

28

The iOS code explained

Page 29: React Native custom components

29

Creating a custom utility component

In the root of your project, use this CLI command to generate yournative component: // In your react-native project $ react-native new-library --name MyComponent

That will create a sample component here (not in ./Libraries?)

./node_modules/react-native/Libraries/MyComponent

Page 30: React Native custom components

30

Creating a custom utility componentThen, you need link it to your application:

Drag and drop your component's .xcodeproj �le into 'Libraries'

Page 31: React Native custom components

31

Creating a custom utility componentFinally, add your static library to the libraries linked to the binary.

Drag and drop your component's .a �le into 'Build Phases'

Page 32: React Native custom components

32

Creating a custom utility component

The important things:

The class has to extend the protocol:<RCTBridgeModule> // MyComponent.h

#import "RCTBridgeModule.h"

@interface MyComponent : NSObject <RCTBridgeModule> @end

That will automagically allow this class to access the React world.

Page 33: React Native custom components

33

Creating a custom utility component

The important things:

The class has to call the RCT_EXPORT_MODULE() macro: // MyComponent.m

@implementation MyComponent

RCT_EXPORT_MODULE(); // Default module name: Same as class name

@end

That will allow you to access, in JS, the module named:

<MyComponent />

Page 34: React Native custom components

34

Creating a custom utility component

The important things:

The class has to call RCT_EXPORT_METHOD() macro if you want tocall a method from your JS code. // MyComponent.m

RCT_EXPORT_METHOD(doSomethingWithThatString:(NSString *)string) { RCTLogInfo(@"A man needs a string: %@", string); }

That will allow you to do, in JS:

MyComponent.doSomethingWithThatString('Hello');

Page 35: React Native custom components

35

Creating a custom utility component

We can (we have to!) �nally wrap our module in a React component. // MyComponent.ios.js var NativeComponent = require('NativeModules').MyComponent;

var MyComponent = { declaringYourLoveTo: function(string) { // You can do a check here, pass a default parameter, etc... NativeComponent.doSomethingWithThatString(string); } };

module.exports = MyComponent;

Finally, in your code:

MyComponent.declaringYourLoveTo('React Native');

Page 36: React Native custom components

36

Creating a custom utility componentA bit more...

RCTConvert is your friend. #import "RCTConvert.h" // ... RCT_EXPORT_METHOD(doSomethingWithThatColor:(NSString *)hexaColor) { UIColor *color = [RCTConvert UIColor:hexaColor]; }

That will allow you to do, in JS:

MyComponent.doSomethingWithThatColor('#123456');

Page 37: React Native custom components

37

Creating a custom utility componentA bit more...

The return type of bridge methods is always void.If you need to get some data from a native method, you'll have to use Promises, as the bridge is asynchronous.

RCT_EXPORT_METHOD(findSomethingAsynchronous, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { NSArray *results = ... if (results) { resolve(results); } else { NSError *error = ... reject(@"no_results", @"There were no results", error); } }

That will allow you to do, in JS:

MyComponent.findSomethingAsynchronous().then((r) => console.log(r));

Page 38: React Native custom components

38

Creating a custom utility componentYour module can also..

Specify which thread its methods should be run onExport constants to JSSend events to JS

#import "RCTBridge.h" #import "RCTEventDispatcher.h"

@implementation MyComponent @synthesize bridge = _bridge;

- (void)methodThatSendsAnEvent { [self.bridge.eventDispatcher sendAppEventWithName:@"CheeseReminder" body:@{@"content": "I love cheese"}]; }

@end

// In JS NativeAppEventEmitter.addListener('CheeseReminder', (reminder) => { console.log(reminder.content); });

Page 39: React Native custom components

39

Page 40: React Native custom components

40

Creating a custom UI component

A UI component is a custom component that renders something.

Same as before, but...

Page 41: React Native custom components

41

Creating a custom UI component

You will create a new class that extends UIView.Your manager (kind of view controller, but singleton) has now tobe a subclass of RCTViewManager. // MyComponentManager.h

#import "RCTViewManager.h"

@interface MyComponentManager : RCTViewManager @end

Page 42: React Native custom components

42

Creating a custom UI component

The manager is responsible of the view. // MyComponentManager.m

#import "MyComponentManager.h" #import "MyComponentView.h"

@implementation MyComponentManager

RCT_EXPORT_MODULE()

- (UIView *)view { return [[MyComponentView alloc] init]; }

...

// Your other RCT_EXPORT_METHOD methods here...

@end

Page 43: React Native custom components

43

Creating a custom UI component

Use RCT_EXPORT_VIEW_PROPERTY() to set things in your view. // MyComponentManager.m RCT_EXPORT_VIEW_PROPERTY(lovingCheese, BOOL)

// MyComponentView.h @interface MyComponentView: UIView

@property (nonatomic, assign) bool lovingCheese;

@end

// MyComponent.ios.js MyComponent.propTypes = { lovingCheese: React.PropTypes.bool, };

Page 44: React Native custom components

44

React-Native-SketchA react-native component for touch-based drawing.

Page 45: React Native custom components

45

React-Native-Sketch

Lessons learned by creating my own custom component:

� It's really cool to publish something to npm� The frequent changes to the API forces you to be reactive� It's harder than I thought to get feedbacks & contributions

Page 46: React Native custom components

46

Conclusion

Custom components can solve a feature request uncovered. Yet.Facebook has created a great tool to allow us extend their tool.If you have to build your own, check the docs regularly.Don't be afraid of native code.

Page 47: React Native custom components

47

ResourcesNative Modules documentationNative UI Components documentationReact-Native View Components (by Brent Vatne)Building Custom React Native Components From Scratch (by JayGarcia)How to Bridge an Objective-C View Component (by Jason Brown)Awesome React-NativeJS.Coach

Page 49: React Native custom components

49

Merci.@jgrancher

Link of this presentation: goo.gl/fpmXem

Page 50: React Native custom components

50

Questions?