# Flutter for React Native Developers This document is for React Native developers looking to apply their existing React Native knowledge to build mobile apps with Flutter. If you understand the fundamentals of the React Native framework, then you can use this document as a jump start your Flutter development. While React Native uses Javascript, Flutter uses a language called Dart. ## A Brief Introduction to Dart for JavaScript Developers [Dart](https://www.dartlang.org/) is an open-source, scalable programming language, for building web, server, and mobile apps. It is an object-oriented, single inheritance language that uses a C-style syntax that is AOT-compiled into native and also transcompiles optionally into JavaScript. It supports interfaces, abstract classes and strong mode. ### Entry Point While JavaScript doesn't have any specific entry function, Dart (like C) does have an entry function called `main()`. ```javascript // JavaScript function main() { // Can be used as entry point } // but it has to be called manually. main(); ``` ```dart // Dart main() { } ``` Try it out in [DartPad](https://dartpad.dartlang.org/0df636e00f348bdec2bc1c8ebc7daeb1). ### Printing to the console Printing data to the console can be done in the following way. ```javascript // JavaScript console.log("Level completed."); ``` ```dart // Dart print('Hello World'); ``` Try it out in [DartPad](https://dartpad.dartlang.org/cf9e652f77636224d3e37d96dcf238e5). ### Variables #### Creating and Assigning Variables While JavaScript variables cannot be typed, Dart variables are optionally typed but it is a good practice to use typed variables. In [Dart 2](https://www.dartlang.org/dart-2), types are mandatory. With both static and runtime type checks, it has a sound type system. This type system enables better tooling, as well as earlier feedback when you write code. ```javascript // JavaScript var name = "JavaScript"; ``` ```dart // Dart String name = 'dart'; var otherName = 'Dart'; // Also inferred to be a String in Strong mode. // Both are acceptable in Dart. ``` Try it out in [DartPad](https://dartpad.dartlang.org/3f4625c16e05eec396d6046883739612). #### Default value In Dart, uninitialized variables have an initial value of `null`. Even variables with numeric types are initially null because numbers are objects in Dart. But in JavaScript, variables are `undefined`. ```javascript // JavaScript var name; // == undefined ``` ```dart // Dart var name; // == null int x; // == null ``` Try it out in [DartPad](https://dartpad.dartlang.org/57ec21faa8b6fe2326ffd74e9781a2c7). **Note:** Check [here](https://www.dartlang.org/resources/dart-tips/dart-tips-ep-3) for more details on variables. ### Checking for null/zero In Dart, only the boolean value true is treated as true. But in JavaScript, values like 1 or any other non-null objects are treated as true. ```javascript // JavaScript var myNull = null; if (!myNull) { console.log("null is treated as false"); } var zero = 0; if (!zero) { console.log("0 is treated as false"); } ``` ```dart // Dart var myNull = null; if (myNull == null) { print('use "== null" to check null'); } var zero = 0; if (zero == 0) { print('use "== 0" to check zero'); } ``` Try it out in [DartPad](https://dartpad.dartlang.org/c85038ad677963cb6dc943eb1a0b72e6). ### Functions For the most part, Dart and JavaScript functions are similar. The only thing that's different in Dart and JavaScript functions is the declaration. ```javascript // JavaScript function fn() { return true; } ``` ```dart // Dart fn() { return true; } // can also be written as bool fn() { return true; } ``` Try it out in [DartPad](https://dartpad.dartlang.org/5454e8bfadf3000179d19b9bc6be9918). **Note:** Check [here](https://www.dartlang.org/resources/dart-tips/dart-tips-ep-6) for more details on functions. ### Asynchronous Programming #### Futures Like JavaScript, Dart supports single-threaded execution. In JavaScript, the `Promise` object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. ```javascript // JavaScript _getIPAddress = () => { const url="https://httpbin.org/ip"; return fetch(url) .then(response => response.json()) .then(responseJson => { this.setState({ _ipAddress: responseJson.origin }); }) .catch(error => { console.error(error); }); }; ``` Whereas Dart uses [`Future`](https://www.dartlang.org/tutorials/language/futures) objects to handle this. ```dart // Dart _getIPAddress() { final url = 'https://httpbin.org/ip'; final httpClient = createHttpClient(); Future response = httpClient.get(url); response.then((value) { setState(() { _ipAddress = JSON.decode(value.body)['origin']; }); }).catchError((error) => print(error)); } ``` Try it out in [DartPad](https://dartpad.dartlang.org/b68eb981456c5eec03daa3c05ee59486). **Note:** Check [here](https://www.dartlang.org/tutorials/language/futures) for more details on future. #### async / await The async function declaration defines an asynchronous function. In JavaScript, when an async function is called, it returns a `Promise`. The `await` operator is used to wait for a `Promise`. ```javascript // JavaScript async _getIPAddress() { const url="https://httpbin.org/ip"; const response = await fetch(url); const json = await response.json(); const data = await json.origin; this.setState({ _ipAddress: data }); } ``` Whereas in Dart,an `async` function returns a `Future`, and the body of the function is scheduled for execution later. The `await` operator is used to wait for a `Future`. ```dart // Dart _getIPAddress() async { final url = 'https://httpbin.org/ip'; final httpClient = createHttpClient(); var response = await httpClient.read(url); String ip = JSON.decode(response)['origin']; setState(() { _ipAddress = ip; }); } ``` Try it out in [DartPad](https://dartpad.dartlang.org/96e845a844d8f8d91c6f5b826ef38951). **Note:** Check [here](https://www.dartlang.org/articles/language/await-async) for more details on async/await. #### Streams A Stream is a sequence of ongoing events that are ordered in time. A Stream is similar to a Future, but a Stream is a sequence of asynchronous events, whereas a Future represents a means for getting a single value sometime in the future. A Stream can emit three different things: * a value (of some type) * an error * a "completed" signal. Streams are cheap and ubiquitous. Anything can be a stream: variables, user inputs, properties, caches, data structures, etc. Generator functions afford us the power of streams in JavaScript. Consider this example in Javascript that makes use of the Generator function: ```javascript // JavaScript var sum=0; function* sumStream () { var n = 1; while (true) { yield sum=sum+n++; } } const nats = Numbers(); function countStream (to){ var i; var sum2; for(i=1;i<=to;i++){ sum2=nats.next().value; } return sum2; } var sum1=countStream (10); console.log(sum1); // 55 ``` In the above example, We keep track of the current number in the sequence with n. We set n = 1 because naturally (pun intended) the natural numbers start with 1. Then, inside an infinite loop, we yield sum added to n which is incremented to the next number in the sequence. In Dart, Streams can be created in many ways, but they can all be used in the same way: the asynchronous for loop (commonly just called await for) iterates over the events of a stream like the for loop iterates over an Iterable. For example: ```dart // Dart Future sumStream(Stream stream) async { var sum = 0; await for (var value in stream) { sum += value; } return sum; } Stream countStream(int to) async* { for (int i = 1; i <= to; i++) { yield i; } } main() async { var stream = countStream(10); var sum = await sumStream(stream); print(sum); // 55 } ``` This code simply receives each event of a stream of integer events, adds them up, and returns (a future of) the sum. When the loop body ends, the function is paused until the next event arrives or the stream is done. Try it out in [DartPad](https://dartpad.dartlang.org/e708f2cc5504f405a374537242a579b5). **Note:** Check [here](https://www.dartlang.org/tutorials/language/streams) for more details on Streams. You can refer [here](https://www.dartlang.org/resources/synonyms) for more differences between Javascript and Dart. ## Learn The Basics of Flutter ### How do I create a Flutter app? In React Native, you would start off your development process by creating the project using the below command line tool. ```sh $ create-react-native-app {projectname} ``` In [Flutter](https://flutter.io/getting-started/), you can use this command line tool to do the same. ```sh $ flutter create {projectname} ``` ### How do I run my app? In React Native, you would go to the project directory and use `npm run ios/android` or `yarn run ios/android`. In [Flutter](https://flutter.io/getting-started/), if you are using the terminal, then you use the `flutter run` command in the project root directory to run your app on a connected device or simulator. If you are using an IDE like IntelliJ, Android Studio, or VS Code with the Flutter plugin installed then you can use the in-built tools to run the app. Refer [here](https://flutter.io/getting-started/) for more details. ### How do I use import statements? ```javascript //React Native import React from "react"; import { StyleSheet, Text, View } from "react-native"; ``` Contrary to React Native’s way of importing each component as they are used, in Flutter, you import the `material.dart` from the flutter package, which allows you to use any material design widget without explicitly importing it. ```dart import 'package:flutter/material.dart'; ``` ### What is the equivalent of React Native `Hello World` app in Flutter? Let’s take a look at how we can define the app in their respective frameworks: ```javascript // React Native import React from "react"; import { StyleSheet, Text, View } from "react-native"; export default class HelloWorldApp extends React.Component { render() { return ( Hello World ); } } ``` ```dart // Flutter import 'package:flutter/material.dart'; void main() => runApp(new HelloWorldApp()); class HelloWorldApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( home: new Scaffold( body: new Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Center( child: new Text( 'Hello World', ), ), ], ), ) ); } } ``` The `HelloWorldApp` class in React Native extends `React.Component` and implements the render method by returning a view component as shown. In Flutter, the execution starts off with the `main()` function inside which a `runApp()` function is used to take the given Widget and make it the root of the widget tree. In the Flutter example above, HelloWorldApp extends StatelessWidget and implements a build method. We have used a MaterialApp widget as the root and passed several other widgets to it as shown. Alternatively, you don't have to use the [`MaterialApp`](https://docs.flutter.io/flutter/material/MaterialApp-class.html) widget when building the HelloWorldApp, you can use the `textDirection` parameter of the [`Text`](https://docs.flutter.io/flutter/widgets/Text-class.html) widget and the [`Center`](https://docs.flutter.io/flutter/widgets/Center-class.html) widget; when the MaterialApp widget is used, providing the text direction is not needed. ### How do I use Widgets and nest them to form a Widget tree? When writing an app, you will commonly author new widgets that are subclasses of either [StatelessWidget](https://docs.flutter.io/flutter/widgets/StatelessWidget-class.html) or [StatefulWidget](https://docs.flutter.io/flutter/widgets/StatefulWidget-class.html), depending on whether your widget manages any state. In the above Hello World example, HelloWorldApp class extends a StatelessWidget and overrides a build function which describes the widget in terms of other, lower-level widgets. In the above example, the widget tree consists of five widgets,the [MaterialApp](https://docs.flutter.io/flutter/material/MaterialApp-class.html),[Scaffold](https://docs.flutter.io/flutter/material/Scaffold-class.html), [Column](https://docs.flutter.io/flutter/widgets/Column-class.html), [Center](https://docs.flutter.io/flutter/widgets/Center-class.html) and the [Text](https://docs.flutter.io/flutter/widgets/Text-class.html) widget. The `MaterialApp` wraps a number of widgets that are commonly required for material design applications and the `Scaffold` implements the basic material design visual layout structure. In simple apps it is easy to nest widgets, but as the code base gets larger and the app becomes complex it is advisable to break deeply nested widgets into functions that return the widget or smaller classes. ##### Preview |Android|iOS| |:---:|:--:| ||| **Note:** You can check the working code for [Flutter](https://github.com/GeekyAnts/flutter-docs-code-samples/blob/master/hello-world/flutterhelloworld/lib/main.dart) and its equivalent [React Native](https://github.com/GeekyAnts/flutter-docs-code-samples/blob/master/hello-world/rnhelloworld/App.js) code. ### How do I create reusable components and use them? In React Native, you create a separate class for a reusable component and use that class as a component. You would then use props to access the passed variables and functions. In the below React Native example, we have created a custom card class and used it inside a parent class. ```javascript // React Native class CustomCard extends React.Component { render() { return ( Card {this.props.index}