Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React-Native custom components

React-Native custom components

React-Native components are awesome. But you can also extend the library yourself by creating a native component, using a bridge between the platform API (iOS, Android) and Javascript.

Jérémy Grancher

June 03, 2016
Tweet

Other Decks in Programming

Transcript

  1. 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
  2. 4 What are you talking about? The current state of

    the React-Native components The need of creating a native component How to do it Lessons learned from creating react-native-sketch
  3. 8 The growth The core components are awesome... ActivityIndicatorIOS DatePickerIOS

    DrawerLayoutAndroid Image ListView MapView Modal Navigator NavigatorIOS PickerIOS Picker ProgressBarAndroid ProgressViewIOS RefreshControl ScrollView SegmentedControlIOS Slider SliderIOS StatusBar Switch TabBarIOS TabBarIOS.Item Text TextInput ToolbarAndroid TouchableHighlight TouchableNativeFeedback TouchableOpacity TouchableWithoutFeedback View ViewPagerAndroid WebView
  4. 10 The Growth Some explanation: The rst commit code On

    the docs: Navigator comparison First look: React-Native Navigator Experimental
  5. 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
  6. 15 The expansion Some important components have been built by

    the community... <Camera /> component by Loch Wansbrough - ★1130
  7. 16 The expansion Some important components have been built by

    the community... <Maps /> component by Leland Richardson - ★912
  8. 17 The expansion Some important components have been built by

    the community... <Video /> component by Brent Vatne - ★689
  9. 18 The expansion Some important components have been built by

    the community... v a r R N F S = r e q u i r e ( ' r e a c t - n a t i v e - f s ' ) ; / / C r e a t e a p a t h y o u w a n t t o w r i t e t o v a r p a t h = R N F S . D o c u m e n t D i r e c t o r y P a t h + ' / t e s t . t x t ' ; / / W r i t e t h e f i l e R N F S . w r i t e F i l e ( p a t h , ' H e l l o R e a c t - N a t i v e S y d n e y ! ' , ' u t f 8 ' ) . t h e n ( ( s u c c e s s ) = > c o n s o l e . l o g ( ' V a l a r M o r g h u l i s ! ' ) ) . c a t c h ( ( e r r ) = > c o n s o l e . l o g ( ' Y o u k n o w n o t h i n g . ' , e r r . m e s s a g e ) ) ; A le-system access by Johannes Lumpe - ★349
  10. 21 The customisation When 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...
  11. 23 The customisation ... or... You have built a native

    iOS / Android component that you want to use in JS without reimplementing the logic. Lucky you. Because react-native will let you create a bridge for it.
  12. 24

  13. 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)
  14. 29 Creating a custom utility component In the root of

    your project, use this CLI command to generate your native component: / / I n y o u r r e a c t - n a t i v e p r o j e c t $ r e a c t - n a t i v e n e w - l i b r a r y - - n a m e M y C o m p o n e n t That will create a sample component here (not in ./Libraries?) . / n o d e _ m o d u l e s / r e a c t - n a t i v e / L i b r a r i e s / M y C o m p o n e n t
  15. 30 Creating a custom utility component Then, you need link

    it to your application: Drag and drop your component's .xcodeproj le into 'Libraries'
  16. 31 Creating a custom utility component Finally, add your static

    library to the libraries linked to the binary. Drag and drop your component's .a le into 'Build Phases'
  17. 32 Creating a custom utility component The important things: The

    class has to extend the protocol: <RCTBridgeModule> / / M y C o m p o n e n t . h # i m p o r t " R C T B r i d g e M o d u l e . h " @ i n t e r f a c e M y C o m p o n e n t : N S O b j e c t < R C T B r i d g e M o d u l e > @ e n d That will automagically allow this class to access the React world.
  18. 33 Creating a custom utility component The important things: The

    class has to call the RCT_EXPORT_MODULE() macro: / / M y C o m p o n e n t . m @ i m p l e m e n t a t i o n M y C o m p o n e n t R C T _ E X P O R T _ M O D U L E ( ) ; / / D e f a u l t m o d u l e n a m e : S a m e a s c l a s s n a m e @ e n d That will allow you to access, in JS, the module named: < M y C o m p o n e n t / >
  19. 34 Creating a custom utility component The important things: The

    class has to call RCT_EXPORT_METHOD() macro if you want to call a method from your JS code. / / M y C o m p o n e n t . m R C T _ E X P O R T _ M E T H O D ( d o S o m e t h i n g W i t h T h a t S t r i n g : ( N S S t r i n g * ) s t r i n g ) { R C T L o g I n f o ( @ " A m a n n e e d s a s t r i n g : % @ " , s t r i n g ) ; } That will allow you to do, in JS: M y C o m p o n e n t . d o S o m e t h i n g W i t h T h a t S t r i n g ( ' H e l l o ' ) ;
  20. 35 Creating a custom utility component We can (we have

    to!) nally wrap our module in a React component. / / M y C o m p o n e n t . i o s . j s v a r N a t i v e C o m p o n e n t = r e q u i r e ( ' N a t i v e M o d u l e s ' ) . M y C o m p o n e n t ; v a r M y C o m p o n e n t = { d e c l a r i n g Y o u r L o v e T o : f u n c t i o n ( s t r i n g ) { / / Y o u c a n d o a c h e c k h e r e , p a s s a d e f a u l t p a r a m e t e r , e t c . . . N a t i v e C o m p o n e n t . d o S o m e t h i n g W i t h T h a t S t r i n g ( s t r i n g ) ; } } ; m o d u l e . e x p o r t s = M y C o m p o n e n t ; Finally, in your code: M y C o m p o n e n t . d e c l a r i n g Y o u r L o v e T o ( ' R e a c t N a t i v e ' ) ;
  21. 36 Creating a custom utility component A bit more... RCTConvert

    is your friend. # i m p o r t " R C T C o n v e r t . h " / / . . . R C T _ E X P O R T _ M E T H O D ( d o S o m e t h i n g W i t h T h a t C o l o r : ( N S S t r i n g * ) h e x a C o l o r ) { U I C o l o r * c o l o r = [ R C T C o n v e r t U I C o l o r : h e x a C o l o r ] ; } That will allow you to do, in JS: M y C o m p o n e n t . d o S o m e t h i n g W i t h T h a t C o l o r ( ' # 1 2 3 4 5 6 ' ) ;
  22. 37 Creating a custom utility component A 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. R C T _ E X P O R T _ M E T H O D ( f i n d S o m e t h i n g A s y n c h r o n o u s , r e s o l v e r : ( R C T P r o m i s e R e s o l v e B l o c k ) r e s o l v e r e j e c t e r : ( R C T P r o m i s e R e j e c t B l o c k ) r e j e c t ) { N S A r r a y * r e s u l t s = . . . i f ( r e s u l t s ) { r e s o l v e ( r e s u l t s ) ; } e l s e { N S E r r o r * e r r o r = . . . r e j e c t ( @ " n o _ r e s u l t s " , @ " T h e r e w e r e n o r e s u l t s " , e r r o r ) ; } } That will allow you to do, in JS: M y C o m p o n e n t . f i n d S o m e t h i n g A s y n c h r o n o u s ( ) . t h e n ( ( r ) = > c o n s o l e . l o g ( r ) ) ;
  23. 38 Creating a custom utility component Your module can also..

    Specify which thread its methods should be run on Export constants to JS Send events to JS # i m p o r t " R C T B r i d g e . h " # i m p o r t " R C T E v e n t D i s p a t c h e r . h " @ i m p l e m e n t a t i o n M y C o m p o n e n t @ s y n t h e s i z e b r i d g e = _ b r i d g e ; - ( v o i d ) m e t h o d T h a t S e n d s A n E v e n t { [ s e l f . b r i d g e . e v e n t D i s p a t c h e r s e n d A p p E v e n t W i t h N a m e : @ " C h e e s e R e m i n d e r " b o d y : @ { @ " c o n t e n t " : " I l o v e c h e e s e " } ] ; } @ e n d / / I n J S N a t i v e A p p E v e n t E m i t t e r . a d d L i s t e n e r ( ' C h e e s e R e m i n d e r ' , ( r e m i n d e r ) = > { c o n s o l e . l o g ( r e m i n d e r . c o n t e n t ) ; } ) ;
  24. 39

  25. 40 Creating a custom UI component A UI component is

    a custom component that renders something. Same as before, but...
  26. 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 to be a subclass of RCTViewManager. / / M y C o m p o n e n t M a n a g e r . h # i m p o r t " R C T V i e w M a n a g e r . h " @ i n t e r f a c e M y C o m p o n e n t M a n a g e r : R C T V i e w M a n a g e r @ e n d
  27. 42 Creating a custom UI component The manager is responsible

    of the view. / / M y C o m p o n e n t M a n a g e r . m # i m p o r t " M y C o m p o n e n t M a n a g e r . h " # i m p o r t " M y C o m p o n e n t V i e w . h " @ i m p l e m e n t a t i o n M y C o m p o n e n t M a n a g e r R C T _ E X P O R T _ M O D U L E ( ) - ( U I V i e w * ) v i e w { r e t u r n [ [ M y C o m p o n e n t V i e w a l l o c ] i n i t ] ; } . . . / / Y o u r o t h e r R C T _ E X P O R T _ M E T H O D m e t h o d s h e r e . . . @ e n d
  28. 43 Creating a custom UI component Use RCT_EXPORT_VIEW_PROPERTY() to set

    things in your view. / / M y C o m p o n e n t M a n a g e r . m R C T _ E X P O R T _ V I E W _ P R O P E R T Y ( l o v i n g C h e e s e , B O O L ) / / M y C o m p o n e n t V i e w . h @ i n t e r f a c e M y C o m p o n e n t V i e w : U I V i e w @ p r o p e r t y ( n o n a t o m i c , a s s i g n ) b o o l l o v i n g C h e e s e ; @ e n d / / M y C o m p o n e n t . i o s . j s M y C o m p o n e n t . p r o p T y p e s = { l o v i n g C h e e s e : R e a c t . P r o p T y p e s . b o o l , } ;
  29. 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
  30. 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.
  31. 47 Resources Native Modules documentation Native UI Components documentation React-Native

    View Components (by Brent Vatne) Building Custom React Native Components From Scratch (by Jay Garcia) How to Bridge an Objective-C View Component (by Jason Brown) Awesome React-Native JS.Coach