What is a React Native Developer

React gets legs

Since its appearance, React Native has undergone an extremely aggressive development: While the GUI stacks of the two platforms were initially completely separate, they have now been standardized, albeit only partially. If you can handle JavaScript competently and are not afraid of some manual labor, you can use React Native applications for Android, iOS and - unofficially - even generate the Universal Windows Platform. In addition to smartphones and tablets, your program can even be installed on the Xbox One. Since articles about working with Android and iOS are now widespread, this one begins with Windows: Most of the concepts discussed here can, however, also be transferred to the other two platforms.

Preparatory

Like most other cross-platform frameworks, React Native lives in the Node.js environment: The first step in starting work with React Native is to download the installation package provided and install it as usual. The following steps are carried out on a 64-bit workstation with Windows 10 1703 - older versions behave largely in the same way.

If you don't want to develop under Windows, open GitHub and click on the BUILDING PROJECTS WITH NATIVE CODE tab. The step-by-step downloading of React Native, which was required in earlier versions of the framework, is now no longer required, as the development team provides a complete package with create-react-native-app. It can be done with the npm command PS C: \ Users \ tamha> npm install -g create-react-native-app to install.

When working with React Native, it makes sense to create a working directory reminiscent of Eclipse and Co. The author collaborates in the following steps C: \ reactplace - Switch to the relevant folder with PowerShell to trigger the creation of a new project skeleton:

PS C: \ reactplace> create-react-native-app SUSWinProject Creating a new React Native app in C: \ reactplace \ SUSWinProject

Do not be surprised that the product downloads some additional components as part of the first start: The ways of the Node Package Manager are in places unfathomable. When the work is done, the in illustration 1 displayed text is output.

Fig. 1: React Native is ready for use - the download can take up to an hour

In the next step, the Windows-specific plug-in must be downloaded. Unlike the main parts of React Native, this may not be in the global assembly cache of the workstation and is instead installed in the project subdirectory:

PS C: \ reactplace> cd. \ SUSWinProject \ PS C: \ reactplace \ SUSWinProject> npm install --save-dev rnpm-plugin-windows

Don't be surprised at warnings regarding the lack of the main React package. It is much more important to use the command line utility in the next step to expand the project PS C: \ reactplace \ SUSWinProject> react-native windows to animate.

If there is a design error when processing the command react-native: The term 'react-native' is not recognized as the name of a cmdletso you have to run the React Native Toolchain separately using the command PS C: \ reactplace \ SUSWinProject> npm install -g react-native-cli download. Run react-native windows then again to complete the generation of a project skeleton that can be used for Visual Studio. Successful completion leads to the in Figure 2 shown result.

Fig. 2: The project structure was generated successfully

As a parallel annoyance, there is a small problem in the project structure generated by React Native: At the time of going to press, only Visual Studio 2015 is supported. The download link for older versions of the IDE is well hidden: open the Visual Studio homepage and scroll down to activate the download link. Users of the free Visual Studio Dev Essentials can download the web installer for the previous version of the IDE: Use the custom setting to install a basic version of Visual Studio 2015. When Visual Studio 2017 is installed, the IDE complains that some modules are already in place and cannot be downloaded again; ignore this error.

The crux of the matter

Fig. 3: A React Native project consists of a group of sub-solutions

After successfully completing the preparatory activities - depending on the workstation and internet connection, two hours can be wasted here - it is now time to get a taste of React Native. In Visual Studio, click FILE | OPEN | PROJECT and select the file windows \ SUSWinProject.sln out. When loading a React Native project for the first time, Visual Studio will prompt you to download a Windows SDK and the Universal Windows Utilities; you agree to both, after which another time goes by. After the work is done, the in Figure 3 Solution structure shown.

ChakraBridge contains a group of libraries that act as brokers between C ++ and C # parts. The projects ReactNativeand ReactNative.Shared serve as repositories for the actual framework code during the project SUSWinProjectprovides the code provided by the developer, including the harness necessary for execution.

Only the file is of particular interest here MainPage.cswhich - strange for Windows universal applications - manages without code behind and has the structure shown in Listing 1.

class MainPage: ReactPage {public override string MainComponentName {get {return "SUSWinProject"; }}}

First there is a function that exposes the name of the JavaScript file serving as the entry point. This string is used by the framework during program execution to identify the class to be used. All packages required in the application are specified in the packages enumeration. This part of the program is always relevant for you if you want to add native additional intelligence to your program (Listing 2).

public override List Packages {get {return new List {new MainReactPackage (),}; }}

Last but not least, there is the declaration of the developer status. It is relevant insofar as returning false instructs the runtime to deactivate the various auxiliary features it contains in the interest of maximum performance (Listing 3).

public override bool UseDeveloperSupport {get {#if! BUNDLE || DEBUG return true; . . . }}

The project generated by the CLI is designed to run on ARM processors. Due to the binary independence of the UWP, however, no emulator is required; simply set the target to x86 or x64 in order to be able to start the program example like any other application. On the author's workstation, React Native turned out to be somewhat cumbersome when clicking Run: During compilation the error Metadata file 'C: \ reactplace \ SUSWinProject \ node_modules \ react-native-windows \ ReactWindows \ ReactNative \ bin \ x86 \ Debug \ ReactNative.dll ‘could not be found occur. In this case, right-click the React Native project (Universal Windows) and command a manual recompilation. The program can then be carried out as usual - the reward for the effort is in Figure 4 errors shown.

Fig. 4: Red means bad - also in the world of React Native

The reason for this behavior, which at first glance seems absurd, is that a React-Native application in debugging mode does not contain any JavaScript code. Instead, this is obtained from the developer's workstation via an auxiliary server during program execution - the file intended for productive applications index.windows.bundle is in from react-native generated project skeleton blank. In PowerShell, return to the project directory and start the program execution by entering react-native start. It takes some time to start the product for the first time; make sure to acknowledge the firewall warning positively. Incidentally, the tool is only ready to start when the bundling process has been completed.

The PowerShell stands!

The display of the highlighting cursor animates PowerShell to stop executing the program; note this if some commands take an unusually long time.

Change the code

Successful deployment in the emulator or device proves that the skeleton generated by the project generator is functional. Unfortunately, we haven't seen any JavaScript code yet: React Native differs from other cross-platform systems in that the JavaScript code lives in its own world. Open the main project folder to reveal two JavaScript files. index.windows.js is - the name suffix speaks a clear language - the Windows-specific version. Its content looks like the one shown in Listing 4.

import React, {Component} from 'react'; import {AppRegistry, StyleSheet, Text, View} from 'react-native';

At the top of the file is the inclusion of some components from the React Native main package. Specifically, we are loading GUI elements at this point that will be used in the following step. The class mentioned in the C # harness we just discussed SUSWinProject is derived from component; it is a basic control. Of particular interest is his render ()Sub-function that returns a structure reminiscent of HTML, as in Listing 5.

class SUSWinProject extends Component {render () {return ( Welcome to React Native! ... ); }}

Developers experienced in React can breathe a sigh of relief at this point: The syntax has been adopted from the "normal" version of the product. Those who switch from other frameworks find the lack of string separators strange at first glance; in practice you get used to it quickly.

The controls appearing on the screen are formatted - similarities to web apps are intended - using a language reminiscent of CSS. Style sheets can be integrated directly into JavaScript files; our current sheet has been greatly shortened (Listing 6).

const styles = StyleSheet.create ({container: {flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '# F5FCFF',} ,...});

Note that the syntactic similarity to CSS is deceptive: The control elements are represented in React Native by the platform's GUI stack, which normally has little knowledge of CSS. It follows that the part of CSS that is supported can vary from widget to widget. Be aware of this before you go insane.

At the end of this file there is another immensely important element: the JavaScript and C # parts of the project are usually not linked. Penetration of the barrier is only allowed for those classes that are exposed by hand - in the case of SUSWinProject this is done with registerComponent above AppRegistry.registerComponent ('SUSWinProject', () => SUSWinProject);.

Do you love us

As with working with Qt, in React Native too, playing ping-pong between the native and the web-based application should be avoided. A classic antipattern would be a pocket calculator, for example, in which a button that is only responsible for changing the display (keyword appending a one) calls a C ++ routine, which in turn interacts with the GUI.

To demonstrate the GUI stack from React Native, we want to implement a small program that uses the classic formula P = U * I can calculate. To do this, some control elements are necessary, which makes us aware of the in Figure 5 structure shown.

Fig. 5: Structure of the React Native control hierarchy

Due to the high level of commonality between Android and iOS, there is a group of control elements in the Basic Components area that are equally available in all mobile operating systems. This also applies to the user interface category: React Native hides three control elements here that are responsible for receiving non-textual input. Behind this formulation, which sounds complex at first glance, there are elements such as a combo box or a slider with which the user can enter numerical values.

They also have in common that mobile platforms for displaying information have more or less complex controls that recycle the widgets used for the actual display. React Native maps this via the ListViews family. Last but not least, there is a group of specific platform controls for iOS and Android that are only available under the respective system. We cannot go into the various other components that are not shown in our diagram at this point - the documentation, which can be viewed online, offers a lot of helpful information at this point.

Our next task is to implement the user interface of our program. For this we want to use three text elements that are responsible for displaying static labels. In addition, three TextInput elements are required through which the user can enter the values ​​to be used for the calculation. Then we place a button on the bottom of the form to start the calculation.

It should be noted that this approach is not necessarily ideal from a usability point of view. In times of ever increasing computing power, it is also advisable in the mobile sector to carry out "small" calculations while entering data.

Low battery?

A really nice feature is to turn off the automatic calculation when the phone's battery drops below a certain level. In addition to the appeal of this feature, which can hardly be ignored for power users, it also provides material for a press release.

In order to keep the "learning effort" within limits, we want to implement our form in stages. First, the content of Render is adjusted (Listing 7).

render () {return ( The controls implemented by React Native act like normal HTML5 widgets: The syntax used to assign properties should be familiar. Another interesting attribute is that React does not work with "instance pointers" whenever possible, but instead interacts with the individual attributes through property fields called props. Each control has its base element, which is considered a reference for resolving references. In the case of our text boxes, this would be the fields, for example textP, textU and textI. At this point, React is tolerant insofar as props do not have to be created as part of a constructor (Listing 8).

); }}

There is a striking difference in the declaration of the button: On the Internet you can always find examples in which the text of the button to be displayed is between the start and the end tag. When working under Windows, this behavior leads to an error, which is why we used the attribute title put.

Last but not least, it is interesting what the function to be called looks like in the event of activation:

class SUSWinProject extends Component {_handlePress () {}

To avoid errors during program execution, the in render () widgets used for the first time in the header of the .js-File to be imported. Whether you sort the imports alphabetically or simply tick the missing classes at the end of the list is entirely up to your taste (Listing 9).

import {. . . Button,. . . TextInput,. . . } from 'react-native';

You can use the code in Listing 9 to update the program. Make sure that the .js-File is saved in the editor of your choice and press CTRL + R. As long as the server is not blocked by a selection, the new form structure appears immediately on the screen.

In theory, we could change the content of the text box by adding a value in textP enroll. This could be done, for example, according to the following scheme:

handlePress () {this.props.textP = "222"; }

If you run the program in this way, you will notice when you click the button that nothing happens. This is because props are considered static; the GUI stack reads them out during the "initialization" of the control tree so that it no longer deals with them afterwards. Instead, dynamic content is stored in a structure called state - to use them, we have to adapt the three text elements according to the scheme in Listing 10.

<TextInput editable = {true} value = {this.state.textU} /> <TextInput editable = {true} value = {this.state.textI} /> <TextInput editable = {true} value = {this.state.textP} />

Note that changes to the state cannot be done by directly writing the variables. Instead, a "transaction" has to be carried out, which is done by code according to the following scheme:

class SUSWinProject extends Component {handlePress () {this.setState ({textP: "Hello!"}); }}

As is so often the case, this somewhat cumbersome procedure can be traced back to a weakness in the JavaScript language specification: The programming language does not provide a way for a program to register for changes to a variable. Incidentally, this is not necessarily nonsensical, as the implementation of such a feature would consume vast amounts of computing power.

In theory, the program would be ready to run in this state; if you actually try, you will get the error message Unable to get property textU ’of undefined or null reference dispatched. This is because React Native checks whether the respective elements are already in place when building a status-based control structure. To solve this problem, it is sufficient to write a constructor into the sample program (Listing 11).

class SUSWinProject extends Component {constructor (props) {super (props); this.state = {textU: "22", textI: "2", textP: ""}; }

It is of particular relevance at this point that we check the incoming parameters using the function Super Passed to the constructor of the base class - this ensures that all information arrives where it is required. Then we just have to adapt the calculation method shown in Listing 12.

handlePress () {var u = this.state.textU; var i = this.state.textI; var pAsString = u * i; this.setState ({textP: pAsString.toString ()}); }

At this point, React Native is stricter than the JavaScript language standard: The one to the members of setState passed elements must be strings; otherwise a warning is issued at runtime. Otherwise the program is ready to be tested for the moment.

Magician of the component

Even if our performance calculator works at this point, it does not meet the specification. Specifically, we are missing the labels that equip the currently colorless input fields with additional context information. In theory, we could just tackle it - it would be more interesting if we took this as an opportunity to deal with the components system from React Native.

Developers can create their own control elements in this framework, which are then equivalent to the elements contained in the framework and are in no way inferior to them in terms of usability. At the level of the index file, create another file called suscomponent.js and equip it with the code shortened by the various inclusions (Listing 13).

import PropTypes from 'prop-types'; export default class SUSComponent extends Component {render () {return ( {this.props.mylabel} ); }}

In addition to loading various components, we also have to do that PropTypes-Provide attribute; it is a group of constants with which you can wire the various properties with data types:

SUSComponent.propTypes = {mylabel: PropTypes.string}; AppRegistry.registerComponent ('SUSComponent', () => SUSComponent);

Components are created in React Native by calling the briefly mentioned above registerComponent-Method: It registers the transferred class under the respective string at runtime. The attributes set in curly brackets implement props that can be parameterized from JSX as part of the invocation.

The inclusion is a nuisance: The React Native Bundler cannot automatically access the missing components. For this reason, the import command must be equipped with a fully-fledged path; the qualification with ./ is necessary:

import SUSComponent from './suscomponent.js';

Last but not least, inclusion takes place in the render ()-Function where the component behaves as expected:

render () {return (

Before the actual deployment, you need to react-native start restart to force the dependency graph to update. From this point on, the label appears on the screen - our first (primitive) component is ready for use.

Do it natively

For reasons of space, we have to end the discussion of React Native at this point. The possibility of integrating additional functions through native code deserves at least a brief mention: React Native allows not only the integration of logic but also the creation of wrappers, the entire control elements for render ()-Make methods approachable. More information can be found on GitHub; alternatively there will be an article on this topic in Windows Developer in the foreseeable future.

Conclusion

React Native and NativeScript both differ from PhoneGap in that they use a full-fledged JavaScript runtime instead of a browser instance, which is connected to the GUI stack of the respective target operating system via proprietary glue. The most important difference between the two frameworks is the way in which the user interfaces are implemented: While Telerik relies on separate XML files, the React user usually works with XML strings integrated into the rest of the code.

The best way to do this is academic: If your company already has intellectual property in React, React Native is definitely a better choice. Otherwise, it is advisable to conduct a developer census and choose the more popular product.

PHP magazine

This article was published in PHP magazine. PHP Magazine covers a wide range of topics that are essential for successful web development.

Of course, you can also read the PHP magazine digitally in the browser or on your Android and iOS devices via the developer.kiosk. The PHP Magazine is still available as a print subscription in our kiosk.