React Native para Web: un vistazo al futuro

 

 

 

  • Smart Interface Design Patterns, 10h video + UX training
  • Design Patterns For AI Interfaces, with Vitaly Friedman

  • Índice
    1. Cómo funciona
    2. Iniciar un nuevo proyecto nativo de React
    3. Gestión de dependencias
    4. Configurando
      1. paquete web.config.js
      2. índice.html
      3. index.web.js
    5. Experimentando con el código
      1. Crear un componente FriendsList.js
      2. amigo.js
      3. Lista de amigos.ios.js
      4. Lista de amigos.web.js
      5. amigo.js
      6. Lista de amigos.js
      7. amigo.js
    6. Conclusión
      1. Recursos
      2. Otras lecturas

    En el artículo anterior, Clayton Anderson le mostró cómo React Native puede ayudarle a crear aplicaciones para iOS y Android con una base de código compartida, sin sacrificar la calidad. Pero ¿qué pasa con la web? React Native para Web está destinado a permitirle escribir una única aplicación que se ejecute en un navegador utilizando tecnologías web estándar, o en iOS y Android como una aplicación móvil nativa real. Si bien no creo que el proyecto esté listo para su uso en producción todavía, su éxito potencial podría marcar un cambio masivo en la forma en que se crean grandes aplicaciones multiplataforma. ¡Saltemos!

     

    Una de las decisiones más difíciles de tomar al iniciar una nueva aplicación es a qué plataformas apuntar. Una aplicación móvil le brinda más control y mejor rendimiento, pero no es tan universal como la web. Si está creando una aplicación móvil, ¿puede permitirse el lujo de admitir tanto iOS como Android? ¿Qué tal intentar crear una aplicación móvil y una aplicación web responsiva? En última instancia, la mejor experiencia para sus clientes es que su aplicación funcione en todas partes, pero los costos de desarrollo y mantenimiento pueden ser prohibitivos.

     

    Ya hemos visto cómo React Native puede ayudarle a crear aplicaciones para iOS y Android con una base de código compartida, sin sacrificar la calidad. Pero ¿qué pasa con la web? Este es exactamente el problema que el proyecto React Native para Web intenta resolver. En lugar de obligarlo a mantener dos bases de código separadas para sus aplicaciones web y móviles, o crear una aplicación híbrida, con todos sus compromisos .

    React Native para Web está destinado a permitirle escribir una única aplicación que se ejecute en un navegador utilizando tecnologías web estándar, o en iOS y Android como una aplicación móvil nativa real. Si bien no creo que el proyecto esté listo para su uso en producción todavía, su éxito potencial podría marcar un cambio masivo en la forma en que se crean grandes aplicaciones multiplataforma. ¡Saltemos!

    Cómo funciona

    Quizás estés pensando: “¡Espera! ¿React ya no funciona en la web? No te equivocarías. Desafortunadamente, React y React Native tradicionales se basan en un conjunto diferente de primitivas. React usa y div, mientras que React Native usa y . Hay buenas razones históricas para esto, ya que los componentes básicos de una página web y de una aplicación móvil son bastante diferentes. No obstante, sería fantástico si pudiéramos utilizar un único conjunto de componentes compartidos.pinputViewTextTextInput

    La solución de React Native para Web es proporcionar implementaciones compatibles con el navegador de los componentes de React Native, lo que significa, por ejemplo, que ViewReact Native tiene una versión basada en DOM que sabe cómo renderizar en un archivo div. Si bien no todos los componentes de React Native son compatibles, hay suficientes como para que (con suerte) puedas compartir la mayor parte de tu código base.

    Además de los componentes en sí, los estilos de React y React Native están escritos de manera diferente. Con React, la mayoría de la gente usa CSS simple o un preprocesador como Sass . Pero en React Native, todos los estilos están escritos en JavaScript, porque no hay DOM ni selectores. Con React Native para Web, los estilos se escriben tal como lo harían con React Native, en lugar de con CSS. Esto tiene la ventaja de permitirle escribir un único conjunto de estilos, que funcionará tanto en dispositivos móviles nativos como en la web.

     

    Más adelante analizaremos en profundidad cómo funcionan estas ideas en la práctica y cuánto código es realmente reutilizable. Primero, pongamos en marcha una aplicación de muestra.

    Iniciar un nuevo proyecto nativo de React

    Para comenzar, necesitaremos configurar nuestro proyecto. Al principio, será solo una aplicación React Native normal y luego agregaremos React Native para Web. Si está siguiendo las instrucciones, deberá completar la guía " Introducción " de React Native antes de pasar a la siguiente sección.

    Una vez que haya instalado React Native, puede ejecutar el siguiente comando desde su terminal:

    react-native init ReactNativeWeb

    Esto creará un nuevo proyecto React Native llamado ReactNativeWeb. Una vez que haya terminado de instalarse, puede cd ReactNativeWeby luego react-native run-ioso react-native run-android. Si todo ha ido correctamente, deberías ver un mensaje amigable de bienvenida en tu simulador o dispositivo iOS o Android.

    Observe que React Native ha creado dos archivos JavaScript en el directorio de nuestro proyecto: index.android.jsy index.ios.js. Puede editar cualquiera de los estilos o lógica en estos archivos y ver esos cambios actualizados en la aplicación en ejecución. Como probablemente puedas adivinar, el .android.jsarchivo es para Android y el .ios.jsarchivo es para iOS. Afortunadamente, solo se necesitan archivos separados cuando desea varias versiones de un archivo determinado por plataforma. La mayoría de las veces, tendrás un único archivo por componente.

    Gestión de dependencias

    Antes de que podamos ejecutar nuestra aplicación en un navegador web, necesitaremos eliminar un poco la instalación del paquete. Primero, ejecute lo siguiente para instalar tanto el react-native-webpaquete como los paquetes web oficiales de React.

    npm i react react-dom react-native-web --save

    (Es posible que vea algunos errores sobre las dependencias de pares de este comando. Debería estar seguro de ignorarlos, porque no me causaron ningún problema. Sin embargo, si hay versiones más nuevas de cualquiera de estos paquetes cuando ejecuta los comandos, puede Es posible que deba ajustar las versiones instaladas).

    En este punto, su package.jsonarchivo debería verse así:

    { "name": "ReactNativeWeb", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { "react": "15.1.0", "react-dom": "15.1.0", "react-native": "0.28.0", "react-native-web": "0.0.25" }}

    Si bien tenemos lo que parece ser todo lo necesario para que nuestra aplicación React Native se ejecute en un navegador web, debemos tomar un breve desvío para considerar las realidades del desarrollo web. El empaquetador de React Native compila su código ECMAScript 6 en algo que el motor JavaScript de un teléfono pueda entender, pero no nos ayudará en el navegador. Si intentáramos ejecutar nuestra aplicación en un navegador web ahora mismo, fallaría rápidamente debido a errores de sintaxis.

    Para resolver este problema, usaremos Babel y webpack . Babel compilará nuestro código ECMAScript 6 en ECMAScript 5 compatible con el navegador, y webpack empaquetará el JavaScript compilado y, en general, acelerará el desarrollo. (Hay otras opciones para esto. Si prefiere otro compilador o paquete, no dude en usarlo).

     

    Estos son los comandos de instalación para ejecutar:

    npm i webpack babel-loader babel-preset-react babel-preset-es2015 --save
    npm i webpack-dev-server --save-dev

    Aquí, babel-loadery webpack-dev-serverse utilizará para agrupar y servir nuestro JavaScript, mientras que babel-preset-reactle babel-preset-es2015dirá a Babel qué complementos necesitamos para compilar nuestro código.

    Así es como package.jsondebería verse su archivo ahora:

    { "name": "ReactNativeWeb", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { "babel-loader": "6.2.4", "babel-preset-es2015": "6.9.0", "babel-preset-react": "6.5.0", "react": "15.1.0", "react-dom": "15.1.0", "react-native": "0.28.0", "react-native-web": "0.0.25", "webpack": "1.13.1" }, "devDependencies": { "webpack-dev-server": "1.14.1" }}

    Configurando

    Esos son todos los paquetes que necesitaremos. Pero se requiere más configuración antes de que nuestra aplicación funcione en un navegador.

    paquete web.config.js

    Primero, crearemos un configarchivo de paquete web. Este archivo le dice a webpack cómo compilar, agrupar y servir nuestro código compilado. Además, usaremos la aliaspropiedad para reemplazar automáticamente las importaciones react-nativecon react-native-web. Este archivo debe colocarse en la raíz de su proyecto.

    const webpack = require('webpack');module.exports = { entry: { main: './index.web.js', }, module: { loaders: [ { test: /.js?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'], }, }, ], }, resolve: { alias: { 'react-native': 'react-native-web', }, },};

    índice.html

    Ahora, necesitamos crear un archivo HTML para que se ejecute nuestra aplicación. Esto será bastante simple porque será solo un esqueleto al que adjuntar nuestra aplicación React.

    !DOCTYPE htmlhtmlhead titleReact Native Web/title meta charSet="utf-8" / meta content="initial-scale=1,width=device-width" name="viewport" //headbody div/div script type="text/javascript" src="/bundle.js"/script/body/html

    index.web.js

    Por último, debemos crear un indexarchivo JavaScript para la web. El contenido de este archivo puede ser el mismo que index.ios.jso index.android.js, pero con una línea adicional para adjuntar al DOM. El div con el ID react-appde nuestro archivo HTML debe seleccionarse y luego usarse en la llamada a AppRegister.runApplication.

    import React, { Component } from 'react';import { AppRegistry, StyleSheet, Text, View} from 'react-native';class ReactNativeWeb extends Component { render() { return ( View style={styles.container} Text style={styles.welcome} Welcome to React Native! /Text Text style={styles.instructions} To get started, edit index.web.js /Text Text style={styles.instructions} Press Cmd+R to reload /Text /View ); }}const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, },});AppRegistry.registerComponent('ReactNativeWeb', () = ReactNativeWeb);AppRegistry.runApplication('ReactNativeWeb', { rootTag: document.getElementById('react-app') });

    Ahora, simplemente ejecute ./node_modules/.bin/webpack-dev-server –inlinepara iniciar el paquete web y abra su navegador parahttps://localhost:8080/ . Crucemos los dedos y verá un mensaje de bienvenida familiar, ¡pero en el navegador! Todo sobre videojuegos

     

    Con toda esa configuración completa, ¡estamos listos para comenzar a jugar!

    Experimentando con el código

    Crear un componente FriendsList.js

    Empecemos por hacer una lista de amigos. Esta será una buena prueba de esfuerzo simple de React Native para Web, porque necesitamos usar algunos componentes diferentes para ello: Image, y .TextViewListView

    import React, { Component } from 'react';import { Image, ListView, StyleSheet, Text, View,} from 'react-native';const styles = StyleSheet.create({ list: { marginTop: 20, }, friend: { flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', }, avatar: { margin: 10, width: 50, height: 50, borderRadius: 25, }, name: { fontSize: 18, color: '#000', }});export default class FriendsList extends Component { constructor(props) { super(props); const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) = r1 !== r2 }); this.state = { ds: ds.cloneWithRows(props.friends), }; } render() { return ( ListView dataSource={this.state.ds} style={styles.list} renderRow={(friend) = View style={styles.friend} Image style={styles.avatar} source={{ uri: friend.avatarUrl }} / Text style={styles.name}{friend.firstName} {friend.lastName}/Text /View } / ); }}

    También necesitaremos editar nuestros indexarchivos para que friendsse pase una matriz como accesorio.

    import FriendsList from './FriendsList';import React, { Component } from 'react';import { AppRegistry, Text, View} from 'react-native';const friends = [ { id: 1, firstName: 'Jane', lastName: 'Miller', avatarUrl: 'https://placehold.it/100x100', }, { id: 2, firstName: 'Kate', lastName: 'Smith', avatarUrl: 'https://placehold.it/100x100', }, { id: 3, firstName: 'Kevin', lastName: 'Yang', avatarUrl: 'https://placehold.it/100x100', },];class ReactNativeWeb extends Component { render() { return FriendsList friends={friends} /; }}AppRegistry.registerComponent('ReactNativeWeb', () = ReactNativeWeb);

    Al ejecutarlo en iOS o Android, deberías ver algo como esto:

    Se ve bien hasta ahora. Veamos la versión web:

    ¡UH oh! Resulta que todavía no hay soporte web para ListView's DataSource, lo que efectivamente lo hace ListViewcompletamente inutilizable.

     

    amigo.js

    Podemos solucionar esta falta de apoyo por ahora. Hagamos un Friendcomponente para las filas individuales, pero tengamos un FriendsListcomponente por plataforma. Esto separará el código compartido que funciona en todas partes pero nos permitirá personalizar cada plataforma donde lo necesitemos.

    import React, { Component } from 'react';import { Image, StyleSheet, Text, View,} from 'react-native';const styles = StyleSheet.create({ friend: { flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', }, avatar: { margin: 10, width: 50, height: 50, borderRadius: 25, }, name: { fontSize: 18, color: '#000', }});export default class Friend extends Component { render() { return ( View style={styles.friend} Image style={styles.avatar} source={{ uri: this.props.avatarUrl }} / Text style={styles.name}{this.props.firstName} {this.props.lastName}/Text /View ); }}

    Lista de amigos.ios.js

    import Friend from './Friend';import React, { Component } from 'react';import { Image, ListView, StyleSheet, Text, View,} from 'react-native';const styles = StyleSheet.create({ list: { marginTop: 20, },});export default class FriendsList extends Component { constructor(props) { super(props); const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) = r1 !== r2 }); this.state = { ds: ds.cloneWithRows(props.friends), }; } render() { return ( ListView dataSource={this.state.ds} style={styles.list} renderRow={(friend) = Friend key={friend.id} avatarUrl={friend.avatarUrl} firstName={friend.firstName} lastName={friend.lastName} / } / ); }}

    En iOS, nuestro ListViewcódigo de uso no cambia. (Por motivos de brevedad, dejaré de lado el ejemplo de código de Android aquí y para el resto del artículo. El código de Android e iOS puede ser el mismo para el resto de los ejemplos de código).

    Lista de amigos.web.js

    import Friend from './Friend';import React, { Component } from 'react';import { Image, Text, View,} from 'react-native';export default class FriendsList extends Component { render() { return ( View {this.props.friends.map(friend = Friend key={friend.id} avatarUrl={friend.avatarUrl} firstName={friend.firstName} lastName={friend.lastName} / )} /View ); }}

    Ahora, para la web, usamos la mapfunción para representar cada uno Friend, similar al React tradicional.

    Mucho mejor. En este punto, escuchar que ListViewrequiere soluciones alternativas puede ser suficiente para hacerle pensar que React Native para Web no está listo para su uso en producción. Me inclino a estar de acuerdo, sobre todo porque las listas constituyen un gran porcentaje de muchas solicitudes. Sin embargo, su importancia variará según el proyecto. Lo bueno es que todo el resto de nuestro código React Native hasta ahora ha sido completamente reutilizable. En cualquier caso, todavía estoy interesado en explorarlo más a fondo, porque todavía hay mucho potencial en las ideas expuestas aquí. Sigamos con nuestra aplicación de muestra.

     

    En lugar de codificar un puñado de elementos de la lista, podemos usar JSON Generator para crear una lista larga con la que podamos trabajar. Si no lo ha usado antes, JSON Generator es una gran herramienta para crear datos ficticios y de desarrollo. Aquí está la estructura que he definido, que agrega algunos campos además de los que ya tenemos.

    [ '{{repeat(200)}}', { id: '{{guid()}}', firstName: '{{firstName()}}', lastName: '{{surname()}}', avatarUrl: 'https://placehold.it/100x100', isOnline: '{{bool()}}', company: '{{company()}}', email: '{{email()}}' }]

    Y aquí hay un fragmento de algunos de los datos generados:

    [ { "id": "c5368bbe-adfb-424f-ade3-9d783befa2b6", "firstName": "Hahn", "lastName": "Rojas", "avatarUrl": "https://placehold.it/100x100", "isOnline": true, "company": "Orbixtar", "email": "[email protected]" }, { "id": "15ef2834-3ba5-4621-abf1-d771d39c2dd6", "firstName": "Helen", "lastName": "Stout", "avatarUrl": "https://placehold.it/100x100", "isOnline": true, "company": "Ebidco", "email": "[email protected]" }, { "id": "1ef05de1-fd8e-41ae-85ac-620b6d716b62", "firstName": "Floyd", "lastName": "Mcpherson", "avatarUrl": "https://placehold.it/100x100", "isOnline": false, "company": "Ecraze", "email": "[email protected]" }, …]

    Para usarlo, simplemente tome su JSON generado y reemplace nuestra friendsdeclaración de matriz anterior. Por supuesto, puedes mover esos datos a su propio archivo si lo deseas, para que tus archivos de código no estén saturados de datos. En una aplicación real, obtendríamos esos datos de un servidor API.

    amigo.js

    A continuación, podemos agregar estos nuevos campos al Friendcomponente.

    …render() { return ( View style={styles.friend} Image style={[styles.avatar, { borderColor: this.props.isOnline ? '#9d9' : '#d99' }]} source={{ uri: this.props.avatarUrl }} / View Text style={styles.name}{this.props.firstName} {this.props.lastName}/Text Text style={styles.company}{this.props.company}/Text Text style={styles.email}{this.props.email}/Text /View /View );}…

    Lista de amigos.js

    A continuación, agréguelos como accesorios en el archivo FriendsList.

    …Friend key={friend.id} avatarUrl={friend.avatarUrl} firstName={friend.firstName} lastName={friend.lastName} isOnline={friend.isOnline} company={friend.company} email={friend.email} /…

    Hasta ahora, todo bien. Es alentador ver que los componentes principales parecen funcionar bien.

    amigo.js

    A continuación, podemos agregar una animación con una transformación para ver qué tan bien funcionan. Hagamos que cuando toques una fila, se anime de izquierda a derecha antes de regresar a su posición inicial. Necesitaremos agregar importaciones para Animatedy TouchableOpacity, conectar la animación y presionar el controlador.

    import { Animated, TouchableOpacity, …} from 'react-native';…export default class Friend extends Component { constructor(props) { super(props); this.state = { translateValue: new Animated.Value(0), }; } animate() { Animated.sequence([ Animated.timing(this.state.translateValue, { toValue: 50, duration: 200, }), Animated.timing(this.state.translateValue, { toValue: -50, duration: 200, }), Animated.timing(this.state.translateValue, { toValue: 0, duration: 200, }) ]).start(); } render() { return ( TouchableOpacity onPress={() = this.animate()} style={[styles.friend, { transform: [{ translateX: this.state.translateValue }]}]} Image style={[styles.avatar, { borderColor: this.props.isOnline ? '#9d9' : '#d99' }]} source={{ uri: this.props.avatarUrl }} / View Text style={styles.name}{this.props.firstName} {this.props.lastName}/Text Text style={styles.company}{this.props.company}/Text Text style={styles.email}{this.props.email}/Text /View /TouchableOpacity ); }}

    Se ve bien en el móvil.

     

    ¿Qué pasa con la web?

    Sin suerte. Nuestro TouchableOpacityarroja un error cuando se presiona. Aparentemente, esto se solucionará en la próxima versión y solo está presente para nuestra combinación particular de versiones. Intentar ejecutar la animación sin usarla TouchableOpacitytambién provoca el mismo error.

    Voy a detenerme aquí, pero si quieres continuar por tu cuenta, aquí tienes una lista de temas que podrías investigar a continuación:

    • ¿Qué tan bien funcionan los componentes y API restantes de React Native? Hemos visto que algunos definitivamente no funcionan, pero aún no tenemos una lista completa de soporte.
    • Podrías explorar un trabajo de estilo más extenso, incluidas las consultas de medios.
    • React Native para Web admite la renderización del servidor. Esto podría ser particularmente interesante porque, si funciona, significaría que podría tener una única base de código que impulse aplicaciones móviles nativas y una aplicación web responsiva optimizada para SEO.

    Conclusión

    Como puede ver, React Native para Web definitivamente no está listo para producción. Hay demasiados componentes no compatibles, incluso en nuestra pequeña aplicación de demostración, para que pueda sentirme seguro al usarlos en un proyecto real. Lo más alentador para mí, sin embargo, es que las piezas que funcionan parecen funcionar completamente, y las que no, fallan por completo. Lo encuentro mucho preferible a que todo funcione . Por el momento, parece que el proyecto sólo necesita más tiempo para conseguir apoyo. Si todo fuera funcional sólo al 50%, lo consideraría una señal de que el enfoque está fundamentalmente roto.

    A pesar de los problemas, sigo pensando que se trata de un proyecto muy interesante y que merece la pena seguir de cerca.

    Recursos

    • Reaccionar nativo para web , GitHub
    • “ Comenzando ”, React Native

    Otras lecturas

    • Por qué debería considerar React Native para su aplicación móvil
    • Cómo escalar las aplicaciones de React
    • Crea tu primera aplicación para iOS con JavaScript
    • Internacionalización de aplicaciones React

    (da, ml, al, mrn)Explora más en

    • Codificación
    • Móvil
    • javascript
    • Aplicaciones
    • Actuación





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    React Native para Web: un vistazo al futuro

    React Native para Web: un vistazo al futuro

    Smart Interface Design Patterns, 10h video + UX training Design Patterns For AI Interfaces, with Vitaly Friedman Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-react-native-para-web-un-vistazo-al-futuro-899-0.jpg

    2024-05-20

     

    React Native para Web: un vistazo al futuro
    React Native para Web: un vistazo al futuro

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20