Flutter for

React & React Native Developer

Majid Hajian

mhadaily

Credit to: JDominik Roszkowski - https://codepen.io/orestesgaolin/pen/ExVboMY

https://chrome-trex-flutter.netlify.app/#/

Credit to: Joshua de Guzman - https://codepen.io/joshuadeguzman/pen/jObrzJB

https://nike-shop-flutter.netlify.app

Credit to: Zoey Fan - https://codepen.io/zoeyfan/pen/ExVaXGK

https://gooey-edge-flutter.netlify.app

mhadaily

Agenda

  • React vs Flutter
  • RN vs Flutter
  • Dart & JS / TS
  • Why!

ME.dart

import 'package:flutter/material.dart';
MaterialApp(
   ThemeData(
        name: "Majid Hajian",
        location: "Oslo, Norway",
        description: '''
                Google Developer Expert
        	Passionate Software engineer, 
	        Community Leader, Author and international Speaker
         ''',
        main: "Flutter/Dart, PWA, Performance",
        homepage: "https://www.majidhajian.com",
        socials: {
          twitter: "https://www.twitter.com/mhadaily",
          github: "https://www.github.com/mhadaily"
          youtube: "https://www.youtube.com/mhadaily"
        },
        author: {
          Pluralsight: "www.pluralsight.com/authors/majid-hajian",
          Apress: "Progressive Web App with Angular, Book",
          PacktPub: "PWA development",
          Udemy: "PWA development",
        }
        founder: "Softiware As (www.Softiware.com)"
        devDependencies: {
          tea: "Ginger", 
          mac: "10.14+",
        },
        community: {
          FlutterVikings: "Orginizer", 
          FlutterDartOslo: "Orginizer",
          GDGOslo: "Co-Orginizer",
          DevFestNorway: "Orginizer",
          ...more
        }));

mhadaily

Find me on the internet by

  • Sharpen your skills
  • Breadth of Knowledge
  • Train your brain
  • Easy to Learn

mhadaily

Similarities

  • Event Loop
  • Just-in-time compilation
  • Ahead-of-time complication
  • Type safe
class User {
  id: number;
	
  constructor(public name: string){id=1};
    
    
   async fetchInfo() {
     return new Promise(
       resolve => setTimeout(resolve, 3*1000);
     );
   }
}


async function main(){

  const user = new User('Majid');
  
  await user.fetchInfo();
  
  console.log(`Hello ${user.id}`)
}
main();
class User {
  final int id;
  final String name;
	
  User(this.name) {id = 1};
    
  fetchInfo() async {
      return Future.delayed(const Duraction(seconds: 2));
   }
}


main() async {

  final user = User('Majid');
  
  await user.fetchInfo();
  
  print('Hello ${user.id}');
}

https://dartpad.dev/

mhadaily

import 'dart:async';

Stream<int> countStream(int to) async* {
  for (int i = 1; i <= to; i++) {
    yield i;
  }
}

main() async {
  
  final count = await countStream(10).first;
  print('first count $count');
  
  countStream(10).listen((v) {
    print('Listen to count $v');
  });
}
import { fromEvent } from 'rxjs';
import { throttleTime, scan } from 'rxjs/operators';

fromEvent(document, 'click')
  .pipe(
    throttleTime(1000),
    scan(count => count + 1, 0)
  )
  .subscribe(count => console.log(`Clicked ${count} times`));

https://dartpad.dev/

mhadaily

Everything is a widget

mhadaily

mhadaily

class HelloWorld extends StatelessWidget {
    @override
    Widget build(BuildContext context){
	    return Text('Hello World');
    }
}
class HelloWorld extends React.Component {
    render() {
    // return '<p>Hello World</p>';
    return <View >
        <Text>Hello world!</Text>
      </View>
    }
}

mhadaily

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/my_widgets.dart';
//React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

mhadaily

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}
const CenterP = ()=>{
// return '<p>Hello World</p>';
     return <View style={styles.container}>
        <Text>Hello world!</Text>
      </View>
}

mhadaily

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  }
});
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Welcome to Flutter'),),
        body: Center(
          child: Text('Hello world'),
        ),
      ),
    );
  }
}

mhadaily

<MyAppHeader>
    <HelloWorld bold></HelloWorld>
</MyAppHeader>

<div style="font-weight:bold; text-align:center;">
	Majid Hajian
</div>

A widget can define:

  • A structural element—like a button or menu
  • A stylistic element—like a font or color scheme
  • An aspect of layout—like padding or alignment
class CustomCard extends StatelessWidget {
  CustomCard({
  required this.index, 
  required this.onPress
  });
  final index;
  final Function onPress;
  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        children: [
          Text('Card $index'),
          TextButton(
            child: const Text('Press'),
            onPressed: this.onPress,
          ),
        ],
      )
    );
  }
}
CustomCard(
  index: index,
  onPress: () { print('Card $index'); },
)
// React Native
class CustomCard extends React.Component {
  render() {
    return (
      <View>
        <Text> 
        Card {this.props.index} 
        </Text>
        <Button
          title="Press"
          onPress={() => this.props.onPress(this.props.index)}
        />
      </View>
    );
  }
}

// Usage
<CustomCard onPress={this.onPress} index={item.key} />
┬
└ projectname
  ┬
  ├ android      - Contains Android-specific files.
  ├ build        - Stores iOS and Android build files.
  ├ ios          - Contains iOS-specific files.
  ├ lib          - Contains externally accessible Dart source files.
    ┬
    └ src        - Contains additional source files.
    └ main.dart  - The Flutter entry point and the start of a new app.
                   This is generated automatically when you create a Flutter
                    project.
                   It's where you start writing your Dart code.
  ├ test         - Contains automated test files.
  └ pubspec.yaml - Contains the metadata for the Flutter app.
                   This is equivalent to the package.json file in React Native.
// pubspec.yaml

flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png


// code 
image: AssetImage('assets/background.png'),
//code 
<Image source={require('./my-icon.png')} />
// Flutter
var data = [ ... ];
ListView.builder(
  itemCount: data.length,
  itemBuilder: (context, int index) {
    return Text(
      data[index],
    );
  },
)
// React Native
<FlatList
  data={[ ... ]}
  renderItem={({ item }) => <Text>{item.key}</Text>}
/>
// Flutter
Center(
  child: Column(
    children: <Widget>[
      Container(
        color: Colors.red,
        width: 100.0,
        height: 100.0,
      ),
      Container(
        color: Colors.blue,
        width: 100.0,
        height: 100.0,
      ),
      Container(
        color: Colors.green,
        width: 100.0,
        height: 100.0,
      ),
    ],
  ),
)
// React Native
<View
  style={{
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    alignItems: 'center'
  }}
>
var container = Container( // grey box
  child: Text(
    "Lorem ipsum",
    textAlign: TextAlign.center,
    style: TextStyle(
      fontSize: 24,
      fontWeight: FontWeight.w900,
      fontFamily: "Georgia",
    ),
  ),
  width: 320,
  height: 240,
  color: Colors.grey[300],
);
<div class="greybox">
    Lorem ipsum
</div>

.greybox {
      background-color: #e0e0e0; /* grey 300 */
      width: 320px;
      height: 240px;
      font: 900 24px Georgia;
      text-align: center;
    }
// Flutter
var textStyle = TextStyle(
    fontSize: 32.0, 
    color: Colors.cyan, 
    fontWeight: FontWeight.w600
   );

///

Center(
  child: Column(
    children: <Widget>[
      Text(
        'Sample text',
        style: textStyle,
      ),
      Padding(
        padding: EdgeInsets.all(20.0),
        child: Icon(Icons.lightbulb_outline,
          size: 48.0, color: Colors.redAccent)
      ),
    ],
  ),
)
// React Native
<View style={styles.container}>
  <Text style={{ fontSize: 32, color: 'cyan', fontWeight: '600' }}>
    This is a sample text
  </Text>
</View>

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

mhadaily

Event

  Widget build(BuildContext context) {
    return GestureDetector(
        child: AbsorbPointer(child : child),
        onTap: () {
          print('tap');
          onTap();
        },
        onTapCancel: () {
          print('tapCancel');
        }
      );
  }
class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
	name = 'majid';
    
    changeName(String str){
    	setState((){
        	name = str;
        });
    }
	
  @override
  Widget build(BuildContext context) {
    ...
  }
}

State Management

// Flutter
class NavigationApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
            ...
      routes: <String, WidgetBuilder>{
        '/a': (BuildContext context) => usualNavscreen(),
        '/b': (BuildContext context) => drawerNavscreen(),
      }
            ...
  );
  }
}


// usage 
Navigator.of(context).pushNamed('/a');
// React Native
const MyApp = TabNavigator(
  { Home: { screen: HomeScreen }, Notifications: { screen: tabNavScreen } },
  { tabBarOptions: { activeTintColor: '#e91e63' } }
);
const SimpleApp = StackNavigator({
  Home: { screen: MyApp },
  stackScreen: { screen: StackScreen }
});
export default (MyApp1 = DrawerNavigator({
  Home: {
    screen: SimpleApp
  },
  Screen2: {
    screen: drawerScreen
  }
}));
React Native Component Flutter Widget Description
Button ElevatedButton A basic raised button.
Button TextButton A basic flat button.
ScrollView ListView A scrollable list of widgets arranged linearly.
FlatList ListView.builder The constructor for a linear array of widgets that are created on demand.
​Image Image A widget that displays an image.
​Modal ModalRoute A route that blocks interaction with previous routes.
ActivityIndicator CircularProgressIndicator
LinearProgressIndicator
A widget that shows progress along a circle.
A widget that shows progress along a line.
Slider Slider Used to select from a range of values.
Text Text The Text widget that displays a string of text with a single style.
TextInput TextInput The interface to the system’s text input control.
TouchableOpacity GestureDetector A widget that detects gestures.
View Container / Column / Row / Center  / Padding 
RefreshControl RefreshIndicator A widget that supports the Material “swipe to refresh” idiom.

Summary

  • React vs Flutter
  • RN vs Flutter
  • Dart & JS / TS

https://docs.flutter.dev/get-started/

https://docs.flutter.dev/get-started/flutter-for/react-native-devs

https://docs.flutter.dev/get-started/flutter-for/web-devs

Majid Hajian

mhadaily

Slides and link to source code

slides.com/mhadaily

SVG icons credited to undraw.co

Flutter for React & React Native Developer

By Majid Hajian

Flutter for React & React Native Developer

After working quite a long time in tech, especially as an architect, I understood that it's not good to be tied to a single framework for a long-time. You might have heard about the technical breadth term! If not, it means you should know what you don't know. It helps you broaden your knowledge, sharpen your skills, and ultimately make a better decision or even have a better career or life. In this session, I will onboard you to Flutter and its ecosystem, where you can start developing the next application right away. You'll learn Flutter based on what you already know. If you have been a React or RN developer, this talk will facilitate and speed up your learning process and help you add another skill to your resume.

  • 943