Categories
React Native

Flex box Layout, Flex Direction

The Flexible Box Module, usually referred to as flexbox, was designed as a one-dimensional layout model, and as a method that could offer space distribution between items in an interface and powerful alignment capabilities

Let’s create a ReactNative Calculator, I prefer to do this calculator design because it gives us better understanding of nested layouts as well as in creating flexible (responsive) design.

Lets go ahead and create a new project

$ react-native init MyCalculatorProj

Open this folder in visual studio code (Make sure to close the metro server if it is already running)

In the terminal tab execute $ react-native run-android

As usual clear the App.js file and replace with

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

const style = StyleSheet.create({
  container:{
    flex:1,
    backgroundColor:'#420C01'
  },
  resultContainer:{
    flex:1
  },
  btnsContainer:{
    flex:4,
    backgroundColor:'#DA7803'
  }
});

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return <View style={style.container}>
      <View style={style.resultContainer}></View>
      <View style={style.btnsContainer}></View>
    </View>
  }
}

The calculator design comprises 3 container boxes,

container:{flex:1,backgroundColor:'#420C01'} is a main wrapper of other 2 containers i.e., resultsContainer and btnsContainer.

This produces following output

  • What makes this partition?, container which is a wrapper having flex value 1, It occupies entire screen with backgroundColor : #420C01
  • The other containers resultsContainer with flex value 1 and btnsContainer with flex value 4 makes the entire screen area divided in to 5
  • resultsContainer takes 1/5 of screen’s height and btnsContainer takes 4/5 of screen’s hight. For width value, we can safely assume screens entire width.
  • The partition happens in vertical direction i.e., height because the parent container flexDirection is ‘column‘ . We did not specify it explicitly because default flexDirection is always column. (We can say in vertical direction), If partition has to happen in horizontal direction we can specify flexDirection:'row' . we will see that in a moment.

Let’s start adding Input buttons of the calculator. We will split the btnsContainer in to 5 (in vertical direction), create a rule btnsRow:{flex:1}

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

const style = StyleSheet.create({
  container:{
    flex:1,
    backgroundColor:'#420C01'
  },
  resultContainer:{
    flex:1
  },
  btnsContainer:{
    flex:4,
    backgroundColor:'#DA7803'
  },
  btnsRow:{
    flex:1
  }
});

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return <View style={style.container}>
      <View style={style.resultContainer}></View>
      <View style={style.btnsContainer}>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
      </View>
    </View>
  }
}

  • We are going to add following buttons in each row.
  • AC, +/-, %, /
  • 7,8,9,x
  • 4,5,6,-
  • 1,2,3,+
  • 0, . , =

But to make this happen, add the flexDirection:'row' to btnsRow

Create following rules inputBtn and inputBtnText

The updated code would be

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

const style = StyleSheet.create({
  container:{
    flex:1,
    backgroundColor:'#420C01'
  },
  resultContainer:{
    flex:1
  },
  btnsContainer:{
    flex:4,
    backgroundColor:'#DA7803'
  },
  btnsRow:{
    flex:1,
    flexDirection:'row'
  },
  inputBtn:{
    flex:1,
    backgroundColor:'#420C01',
    borderWidth:2,
    borderColor:'#FFFFFF',
    borderRadius:4,
    justifyContent:'center',
    alignItems:'center',
    margin:4
  },
  inputBtnText:{
    color:'#FFFFFF',
    fontSize:20,
    fontWeight:'bold'
  }
});

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return <View style={style.container}>
      <View style={style.resultContainer}>
        
      </View>
      <View style={style.btnsContainer}>
        <View style={style.btnsRow}>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>AC</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>+/-</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>%</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>/</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
        <View style={style.btnsRow}></View>
      </View>
    </View>
  }
}

This produces the below output

We have added the flexDirection:’row’ to btnsRow, this will force its children inputBtn container(s) in horizontal direction. Remember flexDirection rule is always enforced to the child container.

Let’s complete all buttons. We use TouchableOpacity Component instead of Button, TouchableOpacity supports all button events such as onPress and acts as a layout container for a Text.

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

const style = StyleSheet.create({
  container:{
    flex:1,
    backgroundColor:'#420C01'
  },
  resultContainer:{
    flex:1
  },
  btnsContainer:{
    flex:4,
    backgroundColor:'#DA7803'
  },
  btnsRow:{
    flex:1,
    flexDirection:'row'
  },
  inputBtn:{
    flex:1,
    backgroundColor:'#420C01',
    borderWidth:2,
    borderColor:'#FFFFFF',
    borderRadius:4,
    justifyContent:'center',
    alignItems:'center',
    margin:4
  },
  inputBtnEqual:{
    flex:2,
    backgroundColor:'#420C01',
    borderWidth:2,
    borderColor:'#FFFFFF',
    borderRadius:4,
    justifyContent:'center',
    alignItems:'center',
    margin:4
  },
  inputBtnText:{
    color:'#FFFFFF',
    fontSize:20,
    fontWeight:'bold'
  }
});

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return <View style={style.container}>
      <View style={style.resultContainer}>

      </View>
      <View style={style.btnsContainer}>
        <View style={style.btnsRow}>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>AC</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>+/-</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>%</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>/</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>7</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>8</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>9</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>X</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>4</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>5</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>6</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>-</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>1</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>2</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>3</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>+</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>0</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>.</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtnEqual}>
            <Text style={style.inputBtnText}>=</Text>
          </TouchableOpacity>
        </View>
      </View>
    </View>
  }
}

The output will be

I have added separate rule for “=” button. i.e., with flex value 2 to get the above output.

Finally add the resultText rule and complete the code

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

const style = StyleSheet.create({
  container:{
    flex:1,
    backgroundColor:'#420C01'
  },
  resultContainer:{
    flex:1
  },
  btnsContainer:{
    flex:4,
    backgroundColor:'#DA7803'
  },
  btnsRow:{
    flex:1,
    flexDirection:'row'
  },
  inputBtn:{
    flex:1,
    backgroundColor:'#420C01',
    borderWidth:2,
    borderColor:'#FFFFFF',
    borderRadius:4,
    justifyContent:'center',
    alignItems:'center',
    margin:4
  },
  inputBtnEqual:{
    flex:2,
    backgroundColor:'#420C01',
    borderWidth:2,
    borderColor:'#FFFFFF',
    borderRadius:4,
    justifyContent:'center',
    alignItems:'center',
    margin:4
  },
  inputBtnText:{
    color:'#FFFFFF',
    fontSize:20,
    fontWeight:'bold'
  },
  resultText:{
    color:'#FFFFFF',
    fontSize:70,
    textAlign:'right',
    margin:10
  }
});

export default class App extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return <View style={style.container}>
      <View style={style.resultContainer}>
          <Text style={style.resultText}>0</Text>
      </View>
      <View style={style.btnsContainer}>
        <View style={style.btnsRow}>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>AC</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>+/-</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>%</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>/</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>7</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>8</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>9</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>X</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>4</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>5</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>6</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>-</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>1</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>2</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>3</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>+</Text>
          </TouchableOpacity>
        </View>
        <View style={style.btnsRow}>
        <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>0</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtn}>
            <Text style={style.inputBtnText}>.</Text>
          </TouchableOpacity>
          <TouchableOpacity style={style.inputBtnEqual}>
            <Text style={style.inputBtnText}>=</Text>
          </TouchableOpacity>
        </View>
      </View>
    </View>
  }
}
Categories
React Native

Hello React Native, Debugging

Lets create our first react native project,

Go to command line and CD to desired directory, In this case, I have a folder called MyReactProject directory in my user directory

execute

$ react-native init MyBaseProject

Once project is fully created, Open the directory “MyBaseProject” in Visual Studio Code.

Let’s start from App.js, remove all codes and type as below

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

const myStyle = StyleSheet.create({
  viewStyle:{
    flex:1,
    justifyContent:'center',
    alignItems:'center'
  },
  textStyle:{
    fontSize:24,
    color:'green'
  }
});


export class MyComponent extends Component{
  constructor(props){
    super(props)
  }

  render(){
    return <View>
      <Text>{this.props.name}</Text>
    </View>
  }
}


export default class App extends Component{
  constructor(props){
    super(props);
    console.log("constructor called");
  }

  render(){
    return <View style={myStyle.viewStyle}>
      <Text style={myStyle.textStyle}>Hello World</Text>
      <MyComponent name="My Custom Component loaded" />
    </View>
  }
}
Above code produces this output

If we closely look React-native stylesheet follows almost all properties of CSS specifications, but with camel casing in the middle.

Following points to be noted

  • Within JSX syntax JavaScript code can be written within single curly brace, example {this.props.name} in MyComponent
  • style attribute of Components (in this example View and Text) expects a JavaScript Object. Not to be confused as double curly brace, eg style={{myStyle.viewStyle}} first curly brace is to allow JavaScript code block and {myStyle.viewStyle} is a JavaScript Object
  • We keep constructor with props argument with super(props), This is to make sure parent class Component props properly executed and ready for further changes in child class. In this case, classes App and MyComponent are the child classes since they are inheriting everything from Component parent class

StyleSheets

Style properties can be written inline as a javascript object. But in above example we have declared a const myStyle and we specify different properties for View, Text Components.

flex

A component can specify the layout of its children using the flexbox algorithm. Flexbox is designed to provide a consistent layout on different screen sizes.

You will normally use a combination of flexDirectionalignItems, and justifyContent to achieve the right layout.

flexDirection

Adding flexDirection to a component’s style determines the primary axis of its layout. Should the children be organised horizontally (row) or vertically (column)? The default is column.

We will look in this section in detail in following sections…

Debugging and reloading

When code is updated, we can refresh the view in Emulator by double tapping R for android, ⌘R if iOS emulator

We can access developer menu by typing ⌘M in Mac or Ctrl+C in windows

Enabling Remote JS Debugging will open the Chrome browser (Right now chrome only supported), we can access inspector window to see console logs

Categories
React Native

React Native CLI Installation

React Native is wonderful in various points

  1. It is JavaScript – No various artificial separation like HTML, CSS, and a coding block
  2. It prepares Native code for Android and iOS – Final generated source code is pure Java and Objective C. No trace of JavaScript
  3. Balances native and hybrid developer concerns – Will discuss on this later

Installation

React native is available as Yarn and NPM package.

Through out this tutorial I am going to use NPM to install modules. Please make sure NodeJS is installed in your PC/Mac

Install React Native Command line interface as a global module.

$ npm -g react-native-cli

For Mac you might be required to prefix sudo.

After successful installation, We can create new react native project called “MyReactNativeProject” using

$ npm react-native init MyReactNativeProject

This will prepare new react native project for you. Once it completes, please make sure we move to the project directory by executing

$ cd MyReactNativeProject

Code Editor

I am going to use Visual Studio code as an Editor, Please download it at ______

Open the project folder in Visual Studio code. And we are ready to roll on

Before making any changes to the code, execute following command

$ react-native run-android

We can see the welcome screen in emulator

App.js

This is the file producing above output. Let’s write

If you notice I am importing React module with out a curly brace enclosing but for Component I am using the curly brace ?

What we have just did? We have written a component class “App” duly inhering a class called “Component”

The view is prepared by the function render(), This function produces the layout and underlying views with the help of View and Text Components. Remember View and Text Component are the components defined in ‘react-native’ modules, these components are fully cross platform and brings native interfaces when running in iOS and Android.

The Component class should have compulsory render function in order to display. But wait, this code looks something like XML? Yes, it is JSX syntax. JSX is a preprocessor step that add XML Syntax to JavaScript.

We would be creating number of such Components and render them when they are required.

State and Props

React Native components are primarily relying on two type of objects.

  1. State – This object is used when component needs to track the change of a value and corresponding view where the said object is displayed
  2. Props – This object is used when component has dependency on other components. Let’s say a Parent component renders a child component, We can assign a props value to Child component from the parent component like below.

Let’s discuss in detail

this.state

React native’s this.state object keeps track of changes, When this object is displayed in render function, During the execution, if somewhere its value modified by a function or a code block, the render function gets refreshed and display the changes immediately.

Look at this code

export default class App extends Component {

  constructor(props){
    super(props);
    this.state = {name:'Vasudev',gender:'Male'};
  }

  changeValueOfState = () => this.setState({name:"Shiva"});


  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center',backgroundColor: '#F5FCFF'}}>
        <Text style={styles.welcome}>{this.state.name}</Text>
      </View>
    );
  }
}

the above example has this.state declared with a value {name:"Vasudev", gender:"Male"} in constructor

Look at the function changeValueOfState, it sets the different value for the name property of this.state object. if this function called during the execution, the render function will pick the changes and display modified state value.

In other words if we try to set new value to this.state object using this.setState function, We can expect the re-rendering to be applied for the specified code block.

this.props

Unlike this.state object, this.props object does not keep track of the changes, in this.props, the data flows in one direction -> From the parent to the child. You can write your own components that use props. The idea behind props is that you can make a single component that is used in many different places in your app

Consider this example

export class MyCustomComponent extends Component{

  constructor(props){
    super(props);
    
  }

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center',backgroundColor: '#F5FCFF'}}>
        <Text>{this.props.name} is from {this.props.city}</Text>
      </View>
    );
  }

}


export default class App extends Component {

  constructor(props){
    super(props);
    
  }


  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center',backgroundColor: '#F5FCFF'}}>
        <MyCustomComponent name="Vasudev" city="Chennai"/>
      </View>
    );
  }
}

Here App being a parent component renders MyCustomComponent as a Child, MyCustomComponent has props called name and city properties. So this name and city values can be set from Parent component as mentioned in above way. Thus the data flows in one direction -> From the parent to the child.

Conclusion

We yet to start the full cycle React Native development but it looks like the concept behind react native is usage of state and props objects, When we require dynamic changes in view we use state object, when we just need to set and display values we use props object.