How to bridge native modules and UI components in React Native by Peggy Rayzis

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone this is Peggy raises and I'm here with react native training today we're going to be learning how to bridge native modules and UI components for both iOS and Android now I know what you're thinking that sounds a bit scary but don't worry I'm going to show you a tool and equip you with the knowledge that you need so you can confidently start bridging in your own react native application I also want to point out that this tutorial covers more of a hello world example so we're not going to be diving into cocoapods or some of the more advanced aspects of bridging for more advanced bridging content check out the react native training blog on medium very soon alright are you ready let's dive in now first we're going to initialize a new react native project by running react native an it we don't have any time to spare today so I went ahead and did that already and I'm calling mine rnt bridging demo but you can call it whatever you'd like you're also going to want to globally install react native create bridge with yarn Creek Bridge is a CLI tool that I built to make bridging native modules and UI components a lot easier it creates templates for you following community best practices in either objective-c or Java or Swift and Kotlin if you prefer today we're going to keep it simple though and stick with Objective C and Java for this tutorial alright the moment you've all been waiting for let's first start out with native UI components first we're going to run create bridge from the root of our react native project the CLI is going to ask you a couple of prompts we're going to name our project I don't know let's call it hello world square because that's what we're going to be building today we're also going to want to choose native UI components our languages objective-c and Java and we're going to deliver our Java Script files to the root directory great if you look here you'll see we already have a Java Script file I'm going to go ahead and require that file in index dot IO SJS and render our newly created view so we can make adjustments natively I'm also going to give it a height and a width here I'm going to come back at the end and explain what's happening in the JavaScript side in just a bit so let's start with iOS first you're going to want to open up Xcode for this now since create bridge does not modify your existing project files you're going to have to add the newly created files to your project by right-clicking on your project file and then clicking add there should be 4 files here generated by the CLI and you're going to want to add all four of those awesome now we have our files so when you bridge native UI components in objective-c you will need two classes your view manager and also your view now for each of those classes you will have a header file now that's your file marks with dot H and then also an implementation file which is dot M now your header file is where you define your public interface you can think of it as like a flow library definition if you're coming from a Java Script background and your implementation file is where you fill in all the details of your class so let's start with the view manager header file first the only notable thing here is that your sub classing off of our CT view manager and this is important because it allows our native component to communicate with the react native bridge now let's break down what's happening in the implementation file the view manager is actually a special type of native module it's a factory whose main purpose is to create your view and act as a delegate for any events you might define only one instance of your view manager is created and just like a native module you expose information to the react native bridge at runtime via compiled time macros such as RCT export module if you want to expose any props to react you can do so with RCT export view property which is what we're doing here with example prop and also if you want to export any constants you would do that here too now keep in mind that accessing constants is synchronous and doesn't require a pass over the bridge great now that we built our view manager let's move on to our view now here we're sub-classing off of UI view but this can be your own custom view if you want any properties that you defined earlier with our CT export view property you're going to want to declare those again the app property marker will define setters and getters for you and don't worry about non-atomic versus atomic that just has to do with thread safety you're also going to want to initialize with the event dispatcher in case you need to send events back to JavaScript now onto the implementation file we're going to need to make some changes here because right now we're not doing much of anything so one thing to keep in mind about bridging UI components in objective-c is that you can't set a background color or a frame directly on the UI view that your view manager is returning because Java Script will override them a way to work around this is to declare a child view and attach it to your UI view so let's do that first let's create an instance variable for our child view we'll create the child view in our initialization method now let's just keep this simple and make it a very basic Blue Square now we can set the background color of our child view and it won't be overridden by anything we set on the JavaScript side now we still need to attach our child view to the parent though and the way you do this is through the UI view lifecycle method layout sub views so in layout sub views we're just going to set the frame of the child view to the bounds of the parent and voila you just add sub view to your UI view awesome now if we run this in the simulator we should see a blue rectangle all right so our blue square is pretty cool but our component is pretty useless if we can't set some properties on it let's create a setter for the property we defined earlier example prop and make it do something to our view so in this method first we're going to check to see if the example prop that's getting passed in is equal to our instance variable and if it's not let's call a method to add some text to our view so now we need to add our textview let's create a UI label we'll also set the text equal to the text that was passed into our example prop you you we'll also make it white size it to fit and attach it to our child view which is the blue rectangle that we rendered earlier and then finally we need to tell our child view to redraw itself so let's go back into JavaScript for a second and change the props now you can change the props and the native component will refresh pretty cool so going back to JavaScript let's backtrack a little bit and talk about what's going on here here we're importing a method require native component from react native now this method takes the name of our view passed as a string and also a class so we can check the components prop types against the types that we expect to see on the native side and that's what we defined earlier with our CT export view property so once the types are checked require native component tells the view manager to create the view and store a reference to it on the bridge then we can render our native component just like any normal react component great now that we finished bridging a native component in iOS let's switch over to Android and bridge a similar component luckily Android tends to be a lot more straightforward than iOS all there although there are some nuances with managing children that you should be aware of so I've already copied what we wrote earlier in index iOS js2 index dot Android is so we can render our component now let's open up Android studio and start diving into some native code since react native create bridge doesn't modify existing project files you're going to need to update in main application Java to tell react to look for the package you just created just add hello world square package to the get packages file and remember to import it above let's go into our hello world square package file now to inspect what's going on all that's really noteworthy here is that you're adding your native components view manager to the create view managers function the concept of a view manager in Android is very similar to that of iOS it's a factory that creates and returns your view now let's dive into our view managers code here we're sub-classing our view manager from the simple view manager class provided by react native this view manager returns a view now it's really important to note that there are different types of view managers if you have multiple children as we did in the previous example for iOS with the Blue Square and also the text view you would need to use a view group manager we're just going to stick with one view today to keep it simple as most often you will probably be using the simple view manager the most in your applications now instead of using compile-time macros like RCT export module to convey information to the bridge we're overriding certain methods such as get name and the name here is the name of the view let's create a review instance here we're going to pass in themed react context and instantiate our view with that context you you we can also set properties like background color on the view directly here unlike iOS if you want to set props onto your need of you annotate them with react prob and use a setter method now we're not going to implement the text view from the previous example because it requires a view group instead of a view but here's where you would set any props awesome so let's run our example just to confirm that everything is working as expected so here we go just having that run and there's our blue rectangle I'd also like to point out that the JavaScript code is completely cross-platform here we didn't change anything so there you have it you just bridge your first native component to your react native application let's move on to native modules luckily native modules are a lot easier in fact we'll be carrying over a lot of the same concepts because view managers are actually a special type of need of module so a lot of this will look familiar to you before we dive into native code we will need to run create bridge again so let's call our module hello world check the box for native modules choose our languages iOS objective-c Android Java and we'll deliver our Java Script files to the root now as we did with our native component files we will need to open up Xcode and add our newly created files to the project there should be two of them here great so let's check out our header file first in this example we're going to learn how to send events over to the JavaScript side from our native module so we will need to subclass our CT event emitter here we're also going to implement the RCT bridge module protocol now this is all standard boilerplate that create bridge exports for you so don't worry about it if it sounds too confusing right now let's switch over to our implementation file just like before we're going to use the macro RCT export module we're also going to declare any constants that we'd like to export now the main purpose of a need of module is to export methods in constants to be consumed on the JavaScript side to export a method use the RCT export method macro and pass in the name of the method here we're going to call ours example method now let's take a look at how we would send events over to JavaScript there are three ways to send events to JavaScript you can use promises you can also use callbacks and event omitting we're going to stick with event omitting in this example since it's probably the easiest and most straightforward way so here in order to do that we're creating a method omit message to react native to send an event we'll call the class method send event with name pass in an event name and also the body of the event now in order to listen for events on the JavaScript side you will need to add the event name to a method called supported events otherwise the native event emitter will not be able to listen to the event and let's just call ours example event here for simplicity now let's fill in the details of example method will return greeting as the key with the value hi friends cool now let's switch over to the JavaScript code and see our native module in action creep bridge has already created the hello world native module file for us so let's open that up this file will be cross-platform first we want to import native modules and native event emitter from react native we're also going to D structure hello world off of native modules here javascript already knows about your need of modules at runtime which is why you can D structure them without having to instantiate them here we're also going to create a new native event emitter now the native event emitter is how we're going to subscribe to events which we'll see in our index IO SJS file for convenience's sake let's wrap our example method our event emitter and also our constant here in an object great now that we got all that out of the way let's import our module in index dot IO SJS here we're going to create a button that when clicked will invoke our example method now once the example method is invoked it will send an event over to the JavaScript side then we want to display our greeting on the screen so first let's add some state for the text cool next in component will mount will add a listener for example event and passing a callback for when we receive the event so here once we receive our example event we're going to set our need of module text state to the greeting that we receive now you can subscribe and component will mount but you always want to remember to tear down all of your listeners in component will unmount and you can do that by calling remove on the emitter so we're also going to need to add an unprecedent on our native module we can also add a touchable opacity in our render method and also a text component to display the text and we'll just do that here awesome now that we have our render method completed let's test this in action we'll run our simulator here and here let's click the button and we receive our sample greeting I'm going to copy index I owe SJS over to index Andrew J s because we will be implementing the same component so let's move on to Android and we'll open Android studio here just like before you will need to add your new hello world package to the get packages function in main application Java and just remember to import that package at the top so let's open up our package in our package we add our module to the create need of modules function similarly to how we added our view manager to the create view manager's function last time and you also pass in the react context here so let's open up our module in our module class we want to extend from the react context base Java module in our constructor we're going to pass in the context and save it to a variable so we can omit events now just like before get name will be the name of your module that you will expose to the react native bridge if you're exporting any constants you can do so by overriding the get constants method and very similar to what we just did in Objective C we're going to create an emit device event method that will use the event emitter to emit event emit an event over to the JavaScript side so now that we have that let's implement the logic for example method so here you're going to want to create a writable map with arguments dot create map and this utility function is already provided to you by react native so it can serialize your event over the bridge because any messages passed over the bridge must be serialized so here we're going to add the key greeting and a sample greeting just like before we're going to give the event the name example event and emit our event over to the JavaScript side so nothing changes over in JavaScript land when we run our application just let the simulator start up here and we click on the button we get our greeting and that's emitting events and native modules in a nutshell remember when you need to pass info from JavaScript over to the native side think method calls and when you need to pass data from the native side over to the JavaScript side you can either emit events use callbacks or promises awesome well you have been a great audience and thank you so much for sticking with me through this video I hope it was informative and will help you start bridging native modules and UI components in your own application if you have any questions feel free to reach out to me at Peggy raĆ­ces on Twitter or you can also file an issue in the react native create bridge repository on github if you're having any trouble getting started so for more awesome react native content on bridging and other topics be sure to follow react native training on YouTube and media see you soon
Info
Channel: React Native Training
Views: 39,772
Rating: undefined out of 5
Keywords: react, reactjs, react native, react-native, ios development, android development, javascript, swift, objective c, kotlin
Id: OrIIPNEjQfs
Channel Id: undefined
Length: 23min 35sec (1415 seconds)
Published: Wed Sep 13 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.