Entering React Native

March 4, 2018

If you are a front-end developer, but also with the experience of react + redux, then you definitely should pay attention to such an interesting tool as the react-native. It allows you to develop cross-platform applications for ios and android. React-native is in the development stage and releases updates every month. Next, I would like to briefly review the main development points for react-native, which I encountered in the process.

At the moment, you can create an application in 2 ways: using create-react-native-app and react-native init. Create-react-native-app is an npm package that allows you to create an initial application structure and run it on your smartphone without installing an environment for each platform. However, if you need to add native code to the application or connect the library that does this, you still have to install the environment.
And now you already have a ready project, but what can you do next? After all, we do not have either CSS or HTML. But we have a jsx syntax, as well as a syntax for styling, very similar to inline styles in html. For layout is used flexbox is the same as on the web. In react-native there are no usual HTML elements for the developer front end, instead there are react-native components for layout, the description of which can be found on the official site. There are cross-platform components (View, Button, TextInput), and also platform-independent (DatePickerIOS, ProgressBarAndroid and others). Let's consider the development of a component by creating a card for displaying the category of words in dictionary. The following is the jsx markup for this component :


<View style={[styles.card, customStyle]} elevation={5}>
    <TouchableNativeFeedback
        onPress={() => onCardBodyClick(categoryId, categoryName)}
        background={TouchableNativeFeedback.Ripple('black')}
    >
        <View style={styles.cardBody}>
            <Text style={styles.bodyText}>{categoryName}</Text>
        </View>
    </TouchableNativeFeedback>

    <View style={styles.cardActions}>
        <ColoredFlatButton onPress={() => onRemove(categoryId)}>
            <Icon size={18} name="close" color="grey" />
        </ColoredFlatButton>
        <ColoredFlatButton onPress={() => onEdit(categoryId)}>
            <Icon size={18} name="mode-edit" color="grey" />
        </ColoredFlatButton>
        <ColoredFlatButton onPress={() => onStudy(categoryId)}>
            <Icon size={18} name="school" color="grey" />
        </ColoredFlatButton>
    </View>
</View>


The view component is similar to a div on the web and is one of the main components when creating a component. TouchableNativeFeedback is a component that allows you to process a click on an element enclosed in it. ColoredFlatButton and Icon components from the library react-native-material-kit. As you can see from the example above, the layout in react-native is no different from the layout in react, except that components are used from react-native instead of HTML elements.

React Native

Next, we'll look at styling this component.


const styles = StyleSheet.create({
   card: {
       marginTop: 10,
       width: 160,
       height: 140,
       justifyContent: 'flex-end',
   },
   cardBody: {
       flex: 1,
       padding: 16,
       justifyContent: 'flex-end',
   },
   bodyText: {
       fontSize: 18,
       color: 'white',
   },
   cardActions: {
       padding: 8,
       flexDirection: 'row',
       backgroundColor: 'white',
       justifyContent: 'space-between',
       alignItems: 'flex-end',
   },
});


In order to create styles, you need to import the StyleSheet class from react-native and pass it a style object. To apply a style to an element, you must specify it in the style attribute.

I think that in styles we don't have to describe, for person familiar with css all would be clear. The only difference is that the dimensions are not specified in CSS units, but in Density-independent Pixels. These are the units that allow an application to look the same on different screens and resolutions in iOS and Android.

After the application appears more than one page, it is worth considering how to make the transition between them. Until recently, adding navigation to the application was quite difficult.

Now the situation has changed, several packages appeared that are recommended in the documentation (native-navigation, react-native-navigation, react-navigation). I used react-navigation. All was simple, just import the navigator and specify the settings.


const RootNavigator = DrawerNavigator(
   {
       [RoutesID.CATEGORY]: {
           screen: CategoryScreen,
           navigationOptions: {
               drawerLabel: 'Categories',
               drawerIcon: ({ tintColor }) => (
                   <Icon name="local-library" color={tintColor} size={22} />
               ),
           },
       },
       [RoutesID.NEW_WORD]: {
           screen: NewWordScreen,
           navigationOptions: {
               drawerLabel: () => null,
           },
       },
   },
   {
       drawerWidth: 250,
       drawerPosition: 'left',
       contentOptions: {
           inactiveTintColor: 'darkgray',
       },
       drawerOpenRoute: 'DrawerOpen',
       drawerCloseRoute: 'DrawerClose',
       drawerToggleRoute: 'DrawerToggle',
   },
);


The first parameter passes application routes, and you can specify the settings for the header of each page. The second parameter is the settings for the Drawer component - this menu is opened on the left by clicking on the burger icon. It is possible to integrate with redux.

After the application has appeared navigation and several screens, you should think about saving the data. If the application does not use an Internet connection, then you need to store data on the device. For this we have SQLite. To work with the database I used the package react-native-sqlite-storage. A little bothered with the installation, and the problem turned out to be obvious, after adding this library to the project it was necessary to reinstall the application on the device. I used a method in which the project already has a database that is used when installing the application on the device, as described on the module page in github. To establish a connection, you only need one line.


open() {
    return SQLite.openDatabase({ name: 'englishAppDB.db', createFromLocation: 1 }).then(
        (db) => {
            this.db = db;

            Promise.resolve();
        },
        error => Promise.reject(error),
    );
}

And also a simple example of a query to the database.
getAllCategories() {
        return this.db.executeSql('SELECT * FROM category', []).then(
            ([{ rows }]) => {
                let category = new List();

                for (let i = 0; i < rows.length; i += 1) {
                    category = category.push(new CategoryRecord({
                        id: rows.item(i).Id,
                        name: rows.item(i).name,
                        color: rows.item(i).color,
                    }));
                }

                return category;
            },
            error => Promise.reject(error),
        );
    }


In conclusion, I can say that after using react-native, I was satisfied with this technology. Convenient debugging in the browser, no difference from debugging web applications. If there is no functions you need, you can always find a library in the community of react-native specialists.

Other posts