Flutter para Desarrolladores React.
Esta es una breve introducción a Flutter para desarrolladores React. Cabe mencionar que para una mejor calidad en la lectura recomiendo leer el articulo original publicado en Medium y Dev.To.a
Introducción a Dart
Lo primero que hay que tener en cuenta es que al igual que React, Flutter usa vistas de estilo reactivo. Sin embargo, mientras React cambia a widgets nativos al trabajar con React Native, Flutter compila todo el código a nativo. Flutter controla cada píxel en la pantalla, lo que evita los problemas de rendimiento causados por la necesidad de un puente a JavaScript.
Dart es un lenguaje fácil de aprender y ofrece las siguientes características:
Proporciona un lenguaje de programación escalable de código abierto para crear aplicaciones web, de servidor y móviles. Proporciona un lenguaje de herencia único orientado a objetos que utiliza una sintaxis de estilo C que se compila en AOT en nativo. Compila opcionalmente en JavaScript. Admite interfaces y clases abstractas.
A continuación se describen algunos ejemplos de las diferencias entre JavaScript y Dart.
Diferencia A) Punto de entrada
JavaScript no tiene una función de entrada predefinida: usted define el punto de entrada.
// JavaScript
function startHere() {
// Can be used as entry point
}
En Dart, cada aplicación debe tener una main()
función de nivel superior que sirva como punto de entrada a la aplicación.
// Dart
main() {
}
Pruébalo en DartPad .
Diferencia B) Variables
Dart es de tipo seguro: utiliza una combinación de verificación de tipo estático y verificaciones de tiempo de ejecución para garantizar que el valor de una variable siempre coincida con el tipo estático de la variable. Aunque los tipos son obligatorios, algunas anotaciones de tipo son opcionales porque Dart realiza inferencia de tipos.
En JavaScript, las variables no se pueden escribir.
En Dart , las variables deben escribirse explícitamente o el sistema de tipos debe inferir el tipo apropiado automáticamente.
// JavaScript
var name = 'JavaScript';// Dart
String name = 'dart'; // Explicitly typed as a string.
var otherName = 'Dart'; // Inferred string.
// Both are acceptable in Dart.
Pruébalo en DartPad .
Para obtener más información, consulte Sistema de tipos de Dart .
Valor por defecto
En JavaScript, las variables no inicializadas son undefined
.
En Dart, las variables no inicializadas tienen un valor inicial de null
. Como los números son objetos en Dart, incluso las variables no inicializadas con tipos numéricos tienen el valor null
.
// JavaScript
var name; // == undefined// Dart
var name; // == null
int x; // == null
Pruébalo en DartPad .
Para obtener más información, consulte la documentación sobre variables .
Diferencia C) Comprobación de nulo o cero
En JavaScript, los valores de 1 o cualquier objeto no nulo se tratan como verdaderos.
// 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');
}
En Dart, solo el valor booleano true
se trata como verdadero.
// 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');
}
Diferencia D) Las funciones
Las funciones de Dart y JavaScript son generalmente similares. La principal diferencia es la declaración.
// JavaScript
function fn() {
return true;
}// Dart
fn() {
return true;
}
// can also be written as
bool fn() {
return true;
}
Pruébalo en DartPad .
Para obtener más información, consulte la documentación sobre funciones .
Los pasos básicos
¿Cómo creo una aplicación Flutter?
Para crear una aplicación usando React Native, debe ejecutar create-react-native-app
desde la línea de comandos.
$ create - react - native - app <nombre del proyecto>
Para crear una aplicación en Flutter, realice una de las siguientes acciones:
- Use un IDE con los complementos Flutter y Dart instalados.
- Use el
flutter create
comando desde la línea de comando. Asegúrese de que el SDK de Flutter esté en su RUTA.
$ flutter create <nombre del proyecto>
Para obtener más información puedes consultas Primeros pasos , una breve guía a través de la creación de una aplicación de contador de clic de botón. Al crear un proyecto Flutter, se compilan todos los archivos que necesita para ejecutar una aplicación de muestra en dispositivos Android e iOS.
¿Cómo ejecuto mi aplicación?
En React Native, ejecutarías npm run
o yarn run
desde el directorio del proyecto.
Puede ejecutar aplicaciones Flutter de dos maneras:
- Use la opción “ejecutar” en un IDE con los complementos Flutter y Dart.
- Usar
flutter run
desde el directorio raíz del proyecto.
Su aplicación se ejecuta en un dispositivo conectado, el simulador de iOS o el emulador de Android.
Para obtener más información, consulte la documentación de inicio de Flutter .
¿Cómo importo widgets?
En React Native, debe importar cada componente requerido.
//React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
En Flutter, para usar widgets de la biblioteca de Diseño de materiales, importe el material.dart
paquete. Para usar widgets de estilo iOS, importe la biblioteca Cupertino. Para usar un conjunto de widgets más básico, importe la biblioteca de widgets. O bien, puede escribir su propia biblioteca de widgets e importarla.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/my_widgets.dart';
Cualquiera que sea el paquete de widgets que importe, Dart extrae solo los widgets que se utilizan en su aplicación.
Para obtener más información, consulte el Catálogo de widgets de Flutter .
¿Cuál es el equivalente de la aplicación React Native “Hello world!” En Flutter?
En React Native, la HelloWorldApp
clase amplía React.Component
e implementa el método de representación devolviendo un componente de vista.
// React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Hello world!</Text>
</View>
);
}
}const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});
En Flutter, puede crear una aplicación idéntica “Hello world!” Utilizando los widgets Center
y Text
de la biblioteca de widgets principales. El Center
widget se convierte en la raíz del árbol de widgets y tiene un hijo, el Text
widget.
// Flutter
import 'package:flutter/material.dart';void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
Las siguientes imágenes muestran la interfaz de usuario de Android e iOS para la aplicación básica Flutter “Hello world!”.
Ahora que ha visto la aplicación Flutter más básica, la siguiente sección muestra cómo aprovechar las ricas bibliotecas de widgets de Flutter para crear una aplicación moderna y pulida.
¿Cómo uso widgets y los anido para formar un árbol de widgets?
En Flutter, casi todo es un widget.
Los widgets son los componentes básicos de la interfaz de usuario de una aplicación. Usted compone widgets en una jerarquía, llamada árbol de widgets. Cada widget anida dentro de un widget padre y hereda propiedades de su padre. Incluso el objeto de la aplicación en sí es un widget. No hay un objeto de “aplicación” separado. En cambio, el widget raíz cumple esta función.
Un widget puede definir:
- Un elemento estructural, como un botón o menú
- Un elemento estilístico, como una fuente o una combinación de colores.
- Un aspecto del diseño, como el relleno o la alineación.
El siguiente ejemplo muestra la aplicación “¡Hola mundo!” Utilizando widgets de la biblioteca de materiales. En este ejemplo, el árbol de widgets está anidado dentro del MaterialApp
widget raíz.
// Flutter
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello world'),
),
),
);
}
}
Las siguientes imágenes muestran “¡Hola, mundo!” Creado a partir de widgets de Material Design. Obtiene más funcionalidad de forma gratuita que en la aplicación básica “Hello world!”.
Al escribir una aplicación, usará dos tipos de widgets: StatelessWidget o StatefulWidget . Un widget sin estado es exactamente lo que parece: un widget sin estado. Un widget sin estado se crea una vez y nunca cambia su apariencia. Un StatefulWidget cambia dinámicamente el estado según los datos recibidos o la entrada del usuario.
La diferencia importante entre los widgets sin estado y con estado es que StatefulWidgets tiene un objeto State que almacena datos de estado y los transfiere a través de las reconstrucciones de árbol, por lo que no se pierde.
En aplicaciones simples o básicas, es fácil anidar widgets, pero a medida que el código base se hace más grande y la aplicación se vuelve compleja, debe dividir widgets profundamente anidados en funciones que devuelvan el widget o clases más pequeñas. Crear funciones y widgets separados le permite reutilizar los componentes dentro de la aplicación.
¿Cómo creo componentes reutilizables?
En React Native, definiría una clase para crear un componente reutilizable y luego usaría props
métodos para establecer o devolver propiedades y valores de los elementos seleccionados. En el siguiente ejemplo, la CustomCard
clase se define y luego se usa dentro de una clase principal.
// 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} />
En Flutter, defina una clase para crear un widget personalizado y luego reutilice el widget. También puede definir y llamar a una función que devuelve un widget reutilizable como se muestra en la build
función en el siguiente ejemplo.
// La clase CustomCard de Flutter extiende StatelessWidget { CustomCard ({ @required this . Index , @required this . OnPress });
índice final ; Función final en Press ;
@anular
Widget build ( BuildContext context ) { return Card (
child : Column (
children : < Widget > [ Text ( 'Card $ index' ), FlatButton (
child : const Text ( 'Press' ),
onPressed : this . OnPress , ), ] , ) ); } } ... // Uso de CustomCard (
index : index , onPress : () {
print ( 'Tarjeta $ índice' ); }, ) ...
En el ejemplo anterior, el constructor de la CustomCard
clase usa la sintaxis de llaves de Dart { }
para indicar parámetros opcionales con nombre .
Para requerir estos campos, elimine las llaves del constructor o agregue @required
al constructor.
Las siguientes capturas de pantalla se muestra un ejemplo de la clase CustomCard reutilizable.