React Native Research Report

Source: Internet
Author: User



Facebook's March open-source framework for the React Native iOS platform has excited both mobile developers and Web developers: Native's mobile developers think more of the estimate is Facebook: "Learn once, write Everywhere, while web developers are excited to estimate that they don't need to learn the unfamiliar OC or swift language of iOS, they can develop native mobile apps in their familiar JavaScript language. So the new react native can carry the two big camp developers look forward to. I and colleagues to react native did a period of research, in the heart gradually have their own answers:



This article assumes that the reader is familiar with iOS app development, but is not knowledgeable about web front-end development (like myself), and on that basis tries to clarify what react native is, how it is used, and whether it is currently worth using.


What is 1.React Native?


First of all, what react native is: It's a set of Facebook open source frameworks designed to use JavaScript to write controls for iOS native . More bluntly, you use JS (JavaScript, hereinafter) written code through the React-native Lib Bridge to the standard iOS program written in Xcode. In the JS program, developers can use a set of react native defined and cocoa Touch UI control class equivalent class, to complete the development of the UI layer, the Xcode compiler will use react-native Lib JS written code compiled into iOS native UI components , showing the use of Xcode view debugging function to demonstrate the results of JS Code compilation, you can see that these JS language is finally compiled into UIView and other objects, rather than H5 interface often used WebView, with this understanding, we on the react Native is not so strange.



In summary, you can think of react native as a framework that allows you to write iOS APP interface logic (v-layer in the MVC framework) using JavaScript instead of traditional objective-c or Swift. The use of swift students will even feel that JS and swift grammar of a lot of similarities (well, the swift five-kernel moon cakes are truly deserved), such as the definition of a variable is the keyword var. The biggest highlights of the framework are the two:


    1. Use JavaScript to write application logic that preserves the original nature of the app, rather than compromising the UI like HTML5, with a high-quality user experience;
    2. Based on the state-driven interface update mechanism, rather than the traditional way through the MVC controller to centrally control the interface update work, the UI and a custom one or some of the state variable function binding, when these variables change, these state variables will drive the corresponding UI module redraw;

      Development environment for 2.React Native

      Use react Native first to build the environment, using react Native for iOS development, the environment is as follows:


The React Native development environment can be built directly in accordance with the guidelines of the Facebook website to build the document, basically without pits and can be completed very quickly.



In addition to creating a running environment, you also need to write JavaScript code in an environment where Xcode is not the best tool! Javascript easy to use editor online a lot, such as Sublime Text, Atom and so on.


3. React Native Technical Composition 3.1 Basic elements


The React Native Library contains both OC code and JavaScript code, which together provide a set of elements for building an interface UI system, including but not limited to:


    • OC Legacy UI components;
    • Gesture recognition and incident response system on OC (e.g. touchablehighlight);
    • Flow-based layout system;

      By flipping through the API documentation on the Facebook website, you can see that it basically implements the most common UI controls on the Cocoa Touch framework:



Basically, we use JS to write our code, and we are using these basic components to build our UI interface. In addition, you can customize your own modules in OC to use in react Native by bridging.


The incident response system in 3.2 React Native


The biggest difference between the local app and the web is that the local app has the perfect incident response system for the user to get a better user experience. In React Native also provides a set of incident response system, grilled react Native source (in the Respondereventplugin.js file), to be able to peep react Native Incident Response basic Flow:



Visible react native's response system is similar to Cocoa touch, a view that needs to implement functions only if it wants to respond to an event:


    • View.props.onStartShouldSetResponder: (EVT) = True-Does the current view want to be the responder for touch?
    • View.props.onMoveShouldSetResponder: (EVT) = True-Does the current view want to be the responder for the move event?


If you return true and try to become the first responder, then one of the following two functions will be called:


    • View.props.onResponderGrant: (evt) = {}-the current view is the first responder, where the interactive effects of the response (such as background color changes) and other logic of event triggering are shown here;
    • View.props.onResponderReject: (evt) = {}-Other view is the first responder;

      Taking into account the complexity of the response system, React Native implements some abstract classes based on the encapsulation of event responses, such as touchblehighlight in UIButton like Cocoa Touch, You can use view to put it where you want to interact. Let's take a look at how to use Touchblehighlight:




3.3 React Native UI update logic


In the Cocoa Touch system, UI updates are typical of the MVC pattern: The Controller updates the view layer's presentation with data changes, but in React Native it is quite different: React Native The state machine mechanism is adopted to drive the update of the entire view layer. Before we start introducing this piece, we have to talk about the react Native rendering method:



From the code snippet given in the previous picture, the reader can also see that the method of building the page is similar to the HTML language: A hierarchical page logic (parent-child relationship) is built through a tagging system, and the layout code is controlled by a separate code using CSS, which separates the business logic from the layout logic. Makes the entire code hierarchy logic clearer.



In React native, the entire UI is a component tree: the UI builds such as the ListView we mentioned earlier are a concrete component,react Native by compiling the component tree into a virtual-dom: a virtual Document Object model, a reader familiar with HTML might be familiar with the DOM, and yes, that DOM, the entire UI relationship can be clearly demonstrated through this virtual-dom , and more importantly, the UI update logic of the React native is also dependent on this tree: We know, in general, that a page update is definitely driven by changes to the data, such as the updating of network data or the occurrence of touch events (as well as follow-up of subsequent business logic) caused by user touches, how can the changes of these data be bound to the refresh of the interface? How do you know which piece of UI to refresh after the data change? It's a thankless thing to know that every data update is redrawing the entire interface: Not only is your app in a high-load state, but the user experience is not good either. React native a state machine by using the user-supplied state variable to drive the UI update of the virtual DOM tree, as shown in:



After the state information is designed, React native calculates that piece of DOM component needs to be updated according to the code logic, the whole process does not need the developer to intervene actively, the developer only need to establish the state system, and according to the data change to maintain state information, React Native will do it all in the background for you.



So what is the state in a component? is actually a property, such as a bool value or an array or any other type of JS support. A Component object actually contains two types of properties: property and state, which are mostly fixed-value properties, while those that change will result in properties that are redrawn on a part of the interface, such as the data source in the list page, How to distinguish whether an attribute should be classified as property or State,facebook React official website document: Think in React detailed introduction, here will not repeat.


Communication mechanism of 3.4 React native


Before we talk about specific communication principles, let's start by looking at how the code is implemented. The communication we are talking about here largely refers to the way in which our JavaScript-written modules and OC-written local modules can be called directly to each other, as shown in:



Before you go into detail, think about the pure OC code, if a class object wants to call the simple case of another class object directly, then the keynote module must know:


    1. Where is the address of the called module?
    2. What is the method name of the called module?
    3. What parameters need to be passed in?

      That is, a complete executable call address must be composed of three units: (module address, method name, parameters), these three are indispensable, the acquisition of these information is mainly through the header file mechanism and Cocoa Touch runtime system to provide. The same is true of the react native communication principle:


We can think of the react native in the JS code module and OC write the local module as two unfamiliar cities, then it is clear that the people between the two cities to communicate effectively, must have a map of each other's city. So in react native world, these two maps are the module configuration table, it looks like the Jiangzi drop (part of the data from the Bang's blog):






Since the two sides of the communication can be resolved through the Module configuration table, then the problem is now simplified to: how to compile and run-time system to provide this table, in order to facilitate further analysis, these two we will communicate the atmosphere JS module call OC Local module and OC Local module call JS module two parts to discuss:


3.4.1 JS module calls OC Local module





An OC module, also known as OC, is a generic class that, by default, cannot be captured by the JavaScript runtime system and is then called, and it must provide or register itself with the compile and runtime system, and expose what properties you want to expose and which methods can be called. The trick is:


    1. When declaring your class, declare yourself to follow the Rctbridgemodule agreement provided by react native (RCT is shorthand for react);
    2. To add a macro to an implemented fileRCT_EXPORT_MODULE();
    3. Use macros to encapsulate the methods you want to exposeRCT_EXPORT_METHOD();

      The code that needs to be added in the called OC Module is as follows (the code comes from the Facebook website):

 
 
// CalendarManager.h
#import "RCTBridgeModule.h"

@interface CalendarManager : NSObject <RCTBridgeModule>
@end
 
// CalendarManager.m
@implementation CalendarManager

RCT_EXPORT_MODULE();

......

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
  RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}
@end


The call mode of the keynote module JS is as follows:


 
var CalendarManager = require(‘NativeModules‘).CalendarManager;
CalendarManager.addEvent(‘Birthday Party‘, ‘4 Privet Drive, Surrey‘);


The exposed method supports the parameter type:


    • String (NSString)
    • Number (Nsinteger, float, double, cgfloat, NSNumber)
    • Boolean (BOOL, NSNumber)
    • Array (Nsarray) of any types from this list
    • Map (Nsdictionary) with the string keys and values of any of the type from the This list
    • function (Rctresponsesenderblock)


Yes, it's that simple! Awesome, isn ' t it? ^_^



In addition, for the OC module to be exposed to the JS module parameters, can be provided by theconstantsToExportmethod, the method returns a dictionary, the sample code is as follows:
In OC module:


- (NSDictionary *)constantsToExport
{
  return @{ @"firstDayOfTheWeek": @"Monday" };
}


The parameters returned by the function can be obtained directly from the JS module:


console.log(CalendarManager.firstDayOfTheWeek);
3.4.2 OC Local module call JS module





OB local class object to invoke the method inside the JS module, you must first follow the protocol mentioned in 3.4.1RCTBridgeModel, the compiler created a module configuration table in addition to the above OC moduleremoteModules, but also saved the JS modulelocalModules. TheRCTBridgeModelprotocol provides aRCTBridgeProperty object that provides a way to access the JS module, with the following code:


 
/**
 * This method is used to call functions in the JavaScript application context.
 * It is primarily intended for use by modules that require two-way communication
 * with the JavaScript code. 
 */
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;


In addition to this direct calling method, Facebookfacebook React Native also provides an indirect way to implement the JS module call, that isRCTEventDispatcher, to send and receive messages in a way to implement the call, the schematic is as follows:



The specific implementation code is as follows:



First, send the notification in the OC Local codeEventReminder:


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

@implementation CalendarManager

@synthesize bridge = _bridge;

- (void)calendarEventReminderReceived:(NSNotification *)notification
{
  NSString *eventName = notification.userInfo[@"name"];
  [self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder"
                                               body:@{@"name": eventName}];
}

@end


Next, listen to the notification in the JS moduleEventReminderand add the corresponding notification response function:


var subscription = DeviceEventEmitter.addListener(
  ‘EventReminder‘,
  (reminder) => console.log(reminder.name)
);
...
// Don‘t forget to unsubscribe, typically in componentWillUnmount
subscription.remove();


By receiving and sending notifications, the coupling degree of OC module and JS module can be reduced, and the realization of this method is also realized byRCTBridgethe direct call method, which is realized by theRCTEventDispatchersource code of sending notification in the viewsendDeviceEventWithName:


- (void)sendDeviceEventWithName:(NSString *)name body:(id)body
{
  [_bridge enqueueJSCall:@"RCTDeviceEventEmitter.emit"
                    args:body ? @[name, body] : @[name]];
}


In conclusion, we can think that the OC module directly calls the JS module communication mode mainly through the object of the protocol, inRCTBridgeModelRCTBridgeaddition tosendDeviceEventWithNamedirectly call the method, you can also use the way of notification indirect call (from Facebookfacebook React Native on the Internet only describes the way the notice, may be able to see that this is the way Facebook recommended, as for the specific use, but also need to excision the developer in context.


Summary of communication mechanism of 3.4.3 React Native


Through the above two sections of code demonstration, we can quickly realize the OC module and JS module Two-way communication, basically, whether it is OC Tune JS or JS tune OC, the core of its dependence is the module configuration table provided by the dual-side module (remote and local), as for its detailed implementation principle, See Bang's blog, which is no longer detailed here.


3.5. React Native UI Layout mechanism


Whether it is a Web page or a native local page, in the development of the UI layout is a very important link, whether the compatibility of multiple-size pages, devices, developers are facing the first issue. With the increasing diversification of the iphone's screen size (at least iphone4s/5s/6/6plus four sizes), Apple has increasingly tended to place the task of UI layout on AutoLayout, AutoLayout a typical relative layout approach , developers add constraints to UI components through a visual editing environment Xib or storyboard, and the runtime system uses the automatic layout engine to calculate frame information for each control in the UI based on the actual screen size, enabling the layout of the UI.



Unlike Cocoa Touch, the React Native uses a completely different system on the UI layout: HTML CSS, which allows developers to write each layout information to a separate style table, and to analyze the layout and business logic, as well as the current streaming layout of the main Web page. Developers use HTML CSS syntax to complete layout information:


var styles = StyleSheet.create({
  scrollView: {
    backgroundColor: ‘#6A85B1‘,
    height: 300,
  },
  button: {
    margin: 7,
    padding: 5,
    alignItems: ‘center‘,
    backgroundColor: ‘#eaeaea‘,
    borderRadius: 3,
  },
  buttonContents: {
    flexDirection: ‘row‘,
    width: 64,
    height: 64,
  },
  img: {
    width: 64,
    height: 64,
  }
});


In addition to using standard HTML CSS for layout, the React native also supports the layout of Flexbox modules, and according to its official website, Flexbox layout module is designed to provide a more efficient way to lay out, Dynamically determines the way in which children in a container are centered, spaced, or even in size.



There are only two types of Flexbox layout objects: the container (container) and the child item within the container (item), as shown in:



For containers and children, there are six or seven layout property keywords, listed as follows:


Properties applied to the Container:
      Display
      Flex-direction
      Flex-wrap
      Flex-flow // = flex-direction + flex-wrap
      Justify-content
      Align-items
      Align-content

The attribute applied to the Item:
      Order
      Flex-grow
      Flex-shrink
      Flex-basis
      Flex // = flex-grow + flex-shrink + flex-basis
      Align-self


CSS in the use of Flexbox only need to add the corresponding keyword directly, as shown in the following code, the meaning of each layout keyword can be obtained through this article:


.flex-container {
  /* We first create a flex layout context */
  display: flex;

  /* Then we define the flow direction and if we allow the items to wrap 
   * Remember this is the same as:
   * flex-direction: row;
   * flex-wrap: wrap;
   */
  flex-flow: row wrap;

  /* Then we define how is distributed the remaining space */
  justify-content: space-around;
}


The layout of the HTML CSS style, compared to the automatic layout of iOS, its dynamic, but only through the pure code to write the layout, it is a bit painful, and for the vast number of iOS mobile ape monkeys without web front-end development experience, CSS layout way to start, Still feel a little strange: basically you have to change a way of thinking to consider the specific layout details, and for more complex dynamic scenarios, this layout may be more difficult to implement and maintenance.


4. Currently, the time to use react native is ripe


At the same time as the react Native hot, we should be careful to discuss the use of react Native the timing is ripe this issue. During this period of research, we found that there are several points worth noting:


4.1 JS module and OC Module data interaction can only be passed through the Dictionary (dictionary)


Dictionary in OC module is a relatively loose data structure, if consider using react native responsible for the UI interface drawing work, OC module is responsible for data processing, then the interaction vector can only be a dictionary. The model class object defined by OC (such as the model object created when using core data) cannot be passed directly to the JS module and must be converted to a dictionary in advance, which is undoubtedly a layer of processing logic that inevitably poses some potential risks.



To use CoreData storage data as an example, our entire data layer interaction will be this way:



This limit can only be passed through the dictionary, which makes it impossible for us to directly use the data object in the OC module as the State property of the JS module to drive the page update. We will have to add a middle tier to transform the data that this change has mapped to the JS module that drives the UI layer of updates.


4.2 React Native The implementation of learn once,write everywhere has yet to be


Facebook emphasized its greatest feature when pushing react native: Learn once, write where. But the reality is that React Native Android is not expected to be released until October 2015, which is a risk for users who want the three-terminal (web/ios/android) architecture to be consistent. And a closer look at the React Native iOS framework, there are many modules tightly coupled to the iOS local modules, such as iOS end of a number of component are iOS only, using the code of these modules, in the future want to run directly on Android is probably impossible, So react native at this point there is still a lot of way to go from the real cross-platform:


**COMPONENTS**
ActivityIndicatorIOS
DatePickerIOS Image ListView
MapView
Navigator
NavigatorIOS
PickerIOS
ScrollView
SliderIOS
SwitchIOS
TabBarIOS
TabBarIOS.Item
ListView performance Issues in 4.3 React Native


There's a issue in GitHub's react native that's especially worrying: ListView renders all rows? Several of these comments reveal the fact that React native's ListView may render all rows at once:


@ide I‘m a noob at instruments profiler... So here‘s brief summary from me taking a look at it.

cpu profile looks like most of the time is spent here (recursing through subviews), in RCTView.m :

- (void)react_updateClippedSubviewsWithClipRect:(CGRect)clipRect relativeToView:(UIView *)clipView
In memory profile major causes of persisted memory (645 MB total) are:

VM: CG Graphics Data (410 MB)
VM: CoreAnimation (141 MB)
VM: JS Garbage Collector (61 MB) ... Unmount the ListView component, and total persisted memory drops to 74 MB total:

VM: JS Garbage Collector 58 MB
VM: CoreUI image data ...
Kureev commented 24 days ago
It‘s totally insane: my iPhone 5c crashes after 700 list items. If I‘m going to write a chat - it‘s blocking for me.

Also I got a lot of "Cannot find single active touch"
samfriend commented 14 days ago
my < ListView pagingEnabled={true} onEndReached={this.loadAnotherFiftyArticles} > 50 rows/pages of < Image / > < Title/ > < Description/ > 3rd Load append (total 150)

Received memory warning

Received memory warning

Received memory warning

Crash Physical iPhone 6 Plus

Also I got a lot of "Cannot find single active touch" time to time


In order to prove the concern of netizens, here we use Xcode view perspective tool to see the React Native official website provided by the Demo:uiexplorer of the ListView, to see if it is a one-time redraw all rows, Shows the interface of this demo runtime:






Then we use Xcode's Debug view hierarchy to look at this tried-and-true interface hierarchy, and the result is shocking: it sure did draw all the row!






Look at a scrollview situation, well, it's not good to see my whole person:






If this is the case, then this one is sufficient to give us reason to choose to abandon the use of react native, at least temporarily!


4.4 React Native UI layout system is not satisfactory


We know that the HTML CSS for the Web front-end that React native uses is also a streaming layout. The entire UI is built from a tree structure, and the layout is based on it, and it needs to be fully manually built. Using a purely code-like approach to writing AutoLayout layouts on iOS is a deep pain in the way of this non-visual layout: You have to transform all the UI impressions into complex layout constraints in your mind.




The layout of the AutoLayout visualization is the most lacking of the react native



Another disadvantage of using CSS layout is that compared to the traditional native layout, the accuracy control is not very good, the final layout effect may be different from the designer's original intention. In the automatic layout AutoLayout we can do a custom layout for the Sizeclass screen, but using CSS is not the way to do it.


4.4 Summary


Through the analysis of the appeal, we found that react native in the performance, the development of convenience, and so on, there are still a lot of shortcomings. At present, it has not achieved its advocacy "learn Once, Write Everywhere" goal, but brought a lot of problems, others do not say, the performance of the ListView is one of the biggest bottlenecks. React native is still in an initial groping phase, its next stage of development, but also to see its old club Facebook next action. Therefore, I suggest that the existing development projects do not risk the use of react Native technology, to maintain technical follow-up.



React Native Research Report


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.