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

Made with Slides.com