Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React

Cómo crear un lector de noticias con React Native: Configuración y elemento de noticias

by
Read Time:21 minsLanguages:
This post is part of a series called How to Create a News Reader With React Native.
How to Create a News Reader With React Native: Web Page Component

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

En este tutorial, crearemos una aplicación de lector de noticias con React Native. En esta serie de dos partes, voy a suponer que esta no es tu primera aplicación React Native y no entraré en detalles sobre la configuración de tu máquina y la ejecución de la aplicación en un dispositivo. Dicho esto, explico el proceso de desarrollo en detalle.

Aunque implementaremos en Android, el código utilizado en este tutorial también debería funcionar en iOS. Así es como se ve el resultado final.

This is what youll be creatingThis is what youll be creatingThis is what youll be creating

Puede encontrar el código fuente utilizado en este tutorial en GitHub.

Requisitos previos

Si eres nuevo en React Native y aún no has configurado tu máquina, asegúrate de consultar la guía de introducción de la documentación de React Native o lee el tutorial introductorio de Ashraff sobre Envato Tuts+. No olvides instalar el SDK de Android si deseas implementarlo en Android o instalar Xcode y el SDK para iOS.

Una vez que haya terminado, instale NodeJS y la herramienta de línea de comandos React Native usando npm.

1. Configuración del proyecto

Ahora estamos listos para construir el proyecto. Antes de comenzar, me gustaría ofrecer una breve descripción de cómo se organiza el proyecto. Creamos dos componentes personalizados:    

  • NewsItems que representa las noticias
  • WebPage que representa la página web cuando el usuario toca una noticia

Estos se importan al archivo de punto de entrada principal para Android (index.android.js) y para iOS (index.ios.js). Eso es todo lo que necesita saber por ahora.

Paso 1: Creando una nueva aplicación

Comience por navegar a su directorio de trabajo. Abra una nueva ventana de terminal dentro de ese directorio y ejecute el siguiente comando:

Esto crea una nueva carpeta llamada HnReader y contiene los archivos necesarios para compilar la aplicación.

React Native ya viene con algunos componentes predeterminados, pero también hay otros personalizados creados por otros desarrolladores. Puede encontrarlos en el sitio web react.parts. Sin embargo, no todos los componentes funcionan tanto en Android como en iOS. Incluso algunos de los componentes predeterminados no son multiplataforma. Es por eso que debe tener cuidado al elegir los componentes, ya que pueden diferir en cada plataforma o pueden no funcionar correctamente en todas las plataformas.

Es una buena idea ir a la página de problemas del repositorio de GitHub del componente que planea usar y buscar compatibilidad con Android o iOS para comprobar rápidamente si el componente funciona en ambas plataformas.

Paso 2: instalar dependencias

La aplicación que vamos a construir depende de unas pocas bibliotecas de terceros y componentes de React. Puede instalarlos abriendo package.json en la raíz de su directorio de trabajo. Agregue lo siguiente a package.json:

A continuación, abra una ventana de terminal en el directorio de trabajo y ejecute npm install para instalar las dependencias especificadas en package.json. Aquí hay una breve descripción de lo que hace cada biblioteca en el proyecto:

  • lodash se usa para truncar cadenas. Puede ser un poco excesivo, pero una línea menos de código que tiene que escribir significa una responsabilidad menos.    
  • moment se utiliza para determinar si las noticias en el almacenamiento local ya están allí por un día.
  • react-native es el marco React Native. Esto se instala de manera predeterminada cuando ejecutaste el react-native init antes.
  • react-native-button es un componente react native utilizado para crear botones.
  • react-native-gifted-spinner se utiliza como un indicador de actividad al realizar solicitudes de red.

2. Componente principal

Como mencioné anteriormente, el punto de entrada para todos los proyectos de React Native es index.android.js e index.ios.js. Ese es el enfoque de esta sección. Reemplace el contenido de estos archivos con lo siguiente:

Déjame desglosarlo. Primero, habilitamos el modo estricto usando la directiva use script. Esto hace que el analizador realice más comprobaciones en su código. Por ejemplo, se quejará si inicializa una variable sin agregar la palabra clave var.

A continuación, importamos el marco React Native. Esto nos permite crear componentes personalizados y agregar estilo a la aplicación.

Luego extraemos toda la funcionalidad que necesitamos del objeto React.

Si es nuevo en ES6 (ECMAScript 6), el fragmento de arriba es idéntico a:

Es el azúcar sintáctico introducido en ES6 para facilitar la asignación de propiedades de objeto a variables. Esto se llama asignación de desestructuración.

Aquí hay una breve descripción de lo que hace cada una de las propiedades que hemos extraído:

  • AppRegistry se usa para registrar el componente principal de la aplicación.
  • StyleSheet se utiliza para declarar estilos para ser utilizados por los componentes.
  • Navigator se usa para cambiar entre las diferentes páginas de la aplicación.

A continuación, importamos los componentes personalizados utilizados por la aplicación. Vamos a crear estos más tarde.

Cree una variable ROUTES y asigne un objeto utilizando los dos componentes anteriores como el valor de sus propiedades. Esto nos permite mostrar el componente haciendo referencia a cada una de las claves que hemos definido.

Cree el componente principal de la aplicación llamando al método createClass desde el objeto React. El método createClass acepta un objeto como argumento.

Dentro del objeto está el método renderScene, que se llama cada vez que cambia la ruta. La route y navigator se pasan como un argumento para este método. La route contiene información sobre la ruta actual (por ejemplo, el nombre de la ruta).

El navigator contiene métodos que se pueden usar para navegar entre diferentes rutas. Dentro del método renderScene, obtenemos el componente que queremos representar pasando el nombre de la ruta actual al objeto ROUTES. A continuación, presentamos el componente y pasamos la route, el navigator y la url como atributos. Más adelante, verás cómo se usan dentro de cada uno de los componentes. Por ahora, solo recuerde que cuando quiera pasar datos desde el componente principal a un componente secundario, todo lo que tiene que hacer es agregar un nuevo atributo y usar los datos que desea pasar como valor.

El método render es un método obligatorio al crear componentes porque es responsable de representar la interfaz de usuario del componente. En este método, renderizamos el componente Navigator y transmitimos algunos atributos.

Permítanme explicar lo que hace cada atributo:

  • el style se usa para agregar estilos al componente.
  • initialRoute se utiliza para especificar la ruta inicial que utilizará el navigator. Como puede ver, hemos pasado un objeto que contiene una propiedad de nombre name con su valor establecido en news_items.  Este objeto es lo que se está pasando al argumento de route del método renderScene, que definimos anteriormente. Esto significa que este código particular representaría el componente NewsItems de forma predeterminada.

La url se establece en una cadena vacía porque no tenemos una página web para procesar de forma predeterminada.    

  • renderScene es responsable de representar el componente para una ruta específica.
  •  configureScene es responsable de especificar las animaciones y los gestos que se utilizarán al navegar entre las rutas. En este caso, estamos pasando una función que devuelve la animación FloatFromRight. Esto significa que, cuando navega hacia una ruta con un índice más alto, la nueva página flota de derecha a izquierda. Y cuando retrocede, flota de izquierda a derecha. Esto también agrega un gesto de deslizar hacia la izquierda como un medio para volver a la ruta anterior.

Los estilos se definen después de la definición del componente principal. Llamamos al método create desde el objeto StyleSheet y pasamos un objeto que contiene los estilos. En este caso, solo tenemos uno, definiendo que va a ocupar toda la pantalla.

Por último, registramos el componente.

3. Componente NewsItem

El componente NewsItem se usa para representar las noticias. Los componentes personalizados se almacenan en el directorio components. Dentro de este directorio, cree news-items.js y añádale el siguiente código:

Paso 1: Importación de componentes y bibliotecas

Primero, importamos los componentes y las bibliotecas que necesitamos para el componente NewsItem. También creamos una variable global que almacena la cantidad total de noticias que se almacenarán en caché.

Usamos algunos componentes que no hemos usado anteriormente.

  • El Text se usa para mostrar texto en React Native.
  • La View es el bloque de construcción básico para crear componentes. Piense en ello como un div en las páginas web.
  • ListView se utiliza para representar una matriz de objetos.
  • ScrollView se usa para agregar barras de desplazamiento. React Native no es como páginas web. Las barras de desplazamiento no se agregan automáticamente cuando el contenido es más grande que la vista o la pantalla. Es por eso que necesitamos usar este componente.
  • TouchableHighlight se utiliza para hacer que un componente responda a eventos táctiles.
  • AsyncStorage no es realmente un componente. Es una API utilizada para almacenar datos locales en React Native.
  • El Button es un componente de terceros para crear botones.
  • GiftedSpinner se usa para crear spinners cuando se cargan datos de la red.
  • api es un módulo personalizado que ajusta fetch, la forma de React Native para hacer solicitudes de red. Hay una gran cantidad de código repetitivo necesario para obtener los datos devueltos por una solicitud de red y es por eso que estamos envolviendo dentro de un módulo. Esto nos permite escribir menos código cuando hacemos solicitudes de red.
  • moment es una biblioteca utilizada para todo lo relacionado con el tiempo.

Paso 2: Creando el componente NewsItems

A continuación, creamos el componente NewsItems:

En este componente se encuentra la función getInitialState, que se utiliza para especificar el estado predeterminado para este componente. En React Native, el estado se usa para almacenar datos que están disponibles en todo el componente. Aquí, almacenamos el título de la aplicación, el dataSource para el componente ListView, las news actuales y un valor booleano, loaded, que indica si las noticias se están cargando o no desde la red. La variable loaded se usa para determinar si se muestra o no el spinner. Lo configuramos en false para que el spinner sea visible por defecto.

Una vez que las noticias se cargan, ya sea desde el almacenamiento local o desde la red, se establece en true para ocultar el cargador. DataSource se utiliza para definir el diseño de la fuente de datos que se utilizará para el componente ListView. Piense en ello como una clase para padres en la que heredarán todas las fuentes de datos que definirá. Esto requiere un objeto que contenga la función rowHasChanged, que le dice a ListView que vuelva a procesar cuando una fila ha cambiado.

Por último, el objeto news contiene el valor inicial para la fuente de datos de ListView.

Paso 3: Implementando la función render

La función de renderizado representa la interfaz de usuario para este componente. Primero, envolvemos todo en una View. Entonces, adentro tenemos el encabezado y el cuerpo. El encabezado contiene el título y el spinner. El cuerpo contiene el ListView. Todo dentro del cuerpo está envuelto dentro de ScrollView para que se agregue automáticamente una barra de desplazamiento si el contenido excede el espacio disponible.

Dentro del encabezado hay dos vistas:

  • uno que contiene el título
  • uno que contiene el spinner

Lo estamos haciendo de esta manera en lugar de enviar el texto y la ruleta directamente para que podamos controlar el estilo utilizando flexbox. Puede ver cómo se hace esto en la sección de estilo, más adelante.

Podemos referirnos al título almacenado en el estado usando this.state, seguido por el nombre de la propiedad. Como habrás notado, cada vez que necesitamos referirnos a un objeto, lo envolvemos con llaves. En la otra vista, estamos verificando si la propiedad loaded en el estado está configurada como false y, si es así, damos salida a la ruleta.

El siguiente es el cuerpo

Tenga en cuenta que hemos pasado un atributo ref al ScrollView. ref es un atributo predefinido en React Native que nos permite asignar un identificador a un componente. Podemos usar este identificador para referirnos al componente y llamar a sus métodos. Aquí hay un ejemplo de cómo funciona esto:

Luego puede tener un botón y hacer que llame a la función presionando. Esto desplazará automáticamente ScrollView a la parte superior del componente.

No usaremos esto en la aplicación, pero es bueno saber que existe.

Dentro de ScrollView, verificamos si la propiedad loaded en el estado ya está configurada en true. Si es true, significa que la fuente de datos ya está disponible para ser utilizada por ListView y podemos renderizarla.

Hemos pasado los siguientes atributos en el ListView:    

  • initialListSize se usa para especificar cuántas filas renderizar cuando el componente se monta inicialmente. Lo hemos establecido en 1, lo que significa que tomará un cuadro para representar cada fila. Lo configuré en 1 como una forma de optimización del rendimiento para que el usuario vea algo lo antes posible.    
  • dataSource es la fuente de datos que se utilizará.    
  • renderRow es la función utilizada para representar cada fila en la lista.

Paso 4: Implementación de la función componentDidMount

A continuación, tenemos la función componentDidMount, que se llama cuando se monta este componente:

Dentro de la función, tratamos de buscar las noticias que están actualmente almacenadas en el almacenamiento local. Usamos el método getItem de la API AsyncStorage. Devuelve una promesa para que podamos obtener acceso a los datos devueltos llamando al método then y pasando una función:

AsyncStorage solo puede almacenar datos de cadena, por lo que usamos JSON.parse para convertir la cadena JSON a un objeto JavaScript. Si es null, llamamos al método getNews, que obtiene los datos de la red.

Si no está vacío, usamos AsyncStorage para buscar la última vez que se almacenaron las noticias en el almacenamiento local. Luego lo comparamos con la hora actual. Si la diferencia es al menos un día (24 horas), buscamos las noticias de la red. Si no es así, usamos los que están en el almacenamiento local.

Paso 5: Implementando la función renderNews

A continuación está la función para representar cada fila en la lista. Anteriormente en el ListView, hemos definido un atributo renderRow, que tiene un valor de this.renderNews. Esta es esa función.

El elemento actual en la iteración se pasa como un argumento a esta función. Esto nos permite acceder al title y la url de cada noticia. Todo está envuelto dentro del componente TouchableHighlight y dentro de él mostramos el título de cada noticia.

El componente TouchableHighlight acepta el atributo onPress, que especifica qué función ejecutar cuando el usuario toca el elemento. Aquí llamamos a la función viewPage y vinculamos la URL a ella. UnderlayColor especifica el color de fondo del componente cuando se toca.

En la función viewPage, obtenemos el atributo de navigator que hemos pasado anteriormente desde index.android.js a través de los accesorios. En React Native, los apoyos se utilizan para acceder a los atributos que se pasan desde el componente principal. Nos referimos a this.props, seguido del nombre del atributo.

Aquí, estamos usando this.props.navigator para referirnos al objeto navigator. A continuación, llamamos al método push para insertar la ruta web_page en el navegador junto con la URL de la página web que abrirá el componente WebPage. Esto hace que la aplicación haga la transición al componente WebPage.

Paso 6: Implementando la función updateNewsItemsUI

La función updateNewsItemsUI actualiza el origen de datos y el estado en función de la matriz de elementos de noticias que se pasó como argumento. Solo lo hacemos si el total de news_items es igual al valor que establecimos anteriormente para TOTAL_NEWS_ITEMS. En React Native, la actualización del estado activa la interfaz de usuario para volver a procesar. Esto significa que llamar a setState con una nueva fuente de datos actualiza la interfaz de usuario con los nuevos elementos.

Paso 7: actualizar el almacenamiento local

La función updateNewsItemDB actualiza las noticias que están almacenadas en el almacenamiento local. Usamos la función JSON.stringify para convertir la matriz en una cadena JSON para que podamos almacenarla usando AsyncStorage.

Paso 8: Obteniendo noticias

La función getNews actualiza el elemento de almacenamiento local que almacena la última vez que se almacenaron los datos en la memoria caché, extrae las noticias de Hacker News API, actualiza la interfaz de usuario y el almacenamiento local en función de los nuevos elementos que se obtuvieron.

El recurso de historias principales en Hacker News API devuelve una matriz que se ve así:

Estos son los identificadores de los artículos principales publicados en Hacker News. Es por eso que tenemos que recorrer este conjunto y hacer una solicitud de red para cada elemento a fin de obtener los detalles reales, como el título y la URL.

Luego lo enviamos a la matriz de news_items y llamamos a las funciones updateNewsItemsUI y updateNewsItemDB para actualizar la interfaz de usuario y el almacenamiento local.

Paso 9: estilo

Agregue los siguientes estilos:

La mayor parte es CSS estándar, pero tenga en cuenta que hemos reemplazado los guiones con la sintaxis de camel case. Esto no se debe a que obtenemos un error de sintaxis si utilizamos algo como padding-left. Es porque es requerido por React Native. También tenga en cuenta que no todas las propiedades CSS se pueden utilizar.

Dicho esto, aquí hay algunas declaraciones que pueden no ser tan intuitivas, especialmente si no has usado flexbox antes:

Aquí hay una versión simplificada del marcado para el componente NewsItems para ayudarlo a visualizarlo:

Hemos configurado container para flex: 1, lo que significa que ocupa toda la pantalla. Dentro del container tenemos el header y el body, que hemos configurado para flex: 1 y flex: 9,  respectivamente. En este caso, flex: 1 no ocupará toda la pantalla ya que el header tiene un hermano. Estos dos compartirán la pantalla completa. Esto significa que toda la pantalla se dividirá en diez secciones, ya que tenemos flex: 1 y flex: 9. Se suman los valores de flex para cada uno de los hermanos.

El header ocupa el 10% de la pantalla y body ocupa el 90% de la misma. La idea básica es elegir un número que represente la altura o el ancho de toda la pantalla y luego cada hermano toma una pieza de este número. Sin embargo, no te excedas con esto. No desea usar 1000 a menos que desee implementar su aplicación en una sala de cine. Encuentro diez para ser el número mágico cuando trabajo con la altura.

Para el header hemos establecido los siguientes estilos:

Y para refrescar su memoria, aquí está el marcado simplificado de lo que está dentro del encabezado:

Y el estilo agregado a aquellos:

Hemos establecido flexDirection para row y justifyContent para space-between en su superior, que es header. Esto significa que sus secundarios se distribuirán de manera uniforme, con el primero al comienzo de la línea y el último al final de la línea.

Por defecto, flexDirection se establece en column, lo que significa que cada uno ocupa toda la línea, ya que el movimiento es horizontal. Usar row haría que el flujo fuera vertical para que cada niño estuviera uno al lado del otro. Si todavía está confundido acerca de Flexbox o si desea obtener más información al respecto, consulte CSS: Flexbox Essentials.

Por último, exponer el componente al mundo exterior:

Conclusión

En este punto, debe tener una buena idea sobre cómo hacer las cosas de la manera React Native. Específicamente, ha aprendido cómo crear un nuevo proyecto React Native, instalar bibliotecas de terceros a través de npm, usar varios componentes y agregar estilo a la aplicación.

En el próximo artículo, continuaremos agregando el componente WebPage a la aplicación News Reader. Siéntase libre de dejar cualquier pregunta o comentario en la sección de comentarios a continuación.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.