El propósito de este tutorial es guiarlo en los primeros pasos con React Native.
Construyamos una aplicación usando la API Maze de TV y siguiendo el prototipo a continuación:

Este tutorial está en construcción. Hasta ahora, cubre los siguientes puntos:
Repositorio con el código listo, también en construcción : https://github.com/erbuen/favtvshow :)
Antes de comenzar a escribir código, es importante comprender los comportamientos asociados con cada pantalla.
Esta es la pantalla que verá el usuario al iniciar la aplicación.

Ella debe tener una barra de búsqueda y, en el lado derecho de la barra, un botón.
La barra de búsqueda debe tener un marcador de posición. Al ingresar una palabra para buscar, debemos usar el botón que el teclado pone a disposición para iniciar la búsqueda, por ejemplo, cómo ocurremos cuando escribimos una URL en el navegador móvil.
Encontrar resultados debe mostrarse debajo de la barra de búsqueda y debajo del título "Resultado de búsqueda", uno por línea. Si no obtiene ningún resultado, debe mostrar el mensaje "No se encontraron resultados".
Los resultados deben mostrarse como "tarjetas" que contienen la imagen, el nombre de la serie y los géneros atribuidos a ella (ver Sección 1.3).
Cuando el usuario selecciona uno de los resultados, debe llevarse a otra pantalla que mostrará la información completa de la serie. Describiremos esta pantalla pronto.
El botón correcto de la barra de búsqueda, cuando se hace clic, debe mostrar la serie favorita del usuario debajo del título "Favoritos".
Si no hay búsqueda en progreso, no muestre nada en la pantalla.
Si no hay una serie favorita, muestre el mensaje "Todavía no tienes una serie favorita".
Cuando el usuario hace clic en una serie, ya sea en los resultados de búsqueda o a favor, debe llevarse a esta pantalla.

Esta pantalla debe mostrar una imagen asociada con la serie, el nombre, los géneros y el resumen.
Junto al nombre y los géneros, debe tener un botón para que el usuario pueda favorecer la serie.
Cuando el usuario hace clic en el botón para favorecer la serie, los datos deben guardar en el almacenamiento global interno de la aplicación y debe haber un retorno visual al usuario que podría ser un "tostado" o similar.
Sobre la imagen de la serie, debe tener un botón de retorno que llevará a la pantalla anterior.
El usuario debe poder enrollar la pantalla ya que el contenido del resumen puede ser mayor que el tamaño de la pantalla del dispositivo.
Verá una lista de series cuando busque y obtenga al menos un resultado o cuando acceda a su serie favorita.
Para este propósito, debemos construir un componente de tarjeta como imagen a continuación:

Las tarjetas deben hacer clic y mostrar en una lista plana.
¡Ha llegado el momento de comenzar el proyecto! Para hacer esto, visite la página React Native y haga clic en Comenzar .

En la página de inicio , encontrará toda la información que necesita para comenzar con React Native. Para este tutorial, le sugerimos que elija la opción React Native ClickStart .

Luego elija la mejor opción que se ajuste a su perfil. En mi caso, me desarrollaré usando una Mac, por lo que en el desarrollo los elegí y, como probaré usando el iPhone, en el objetivo , elegí el objetivo como iOS , pero podría haber elegido Android .

Solo puede elegir Target como iOS si está utilizando una Mac. Para Windows y Linux , necesariamente debe elegir Android .
Después de seleccionar las opciones de acuerdo con su sistema operativo, siga las instrucciones para instalar las instalaciones requeridas para usar React Native.
Después de completar la instalación de todas las dependencias de acuerdo con el paso por paso del sitio de React Native, podrá iniciar su proyecto con el siguiente comando:
npx react-native init NomeDoProjetoLa creación del proyecto puede tomar unos minutos, no se preocupe y seguir los registros a través de la terminal :)
Cuando se completa el proceso, puede ejecutar su proyecto con los siguientes comandos:
cd NomeDoProjeto
npx react-native run-iosSi está usando macOS. O, si está utilizando Windows o Linux:
cd NomeDoProjeto
npx react-native run-androidDespués de un tiempo, y la primera vez que ejecutamos este comando realmente puede llevar mucho tiempo, verá algo así (dependiendo del sistema operativo objetivo ):

IMPORTANTE: Tenga en cuenta que el texto del proyecto predeterminado en la primera ejecución (sin cambios) menciona opciones para que vea sus cambios (recarga) y también para depurar. Esto significa que puede cambiar el código y ver los cambios y hacer la depuración en tiempo real.
Para que modifique el proyecto, debe usar un editor de código de su elección:
Al abrir el proyecto en el editor de código de su elección, verá esta carpeta y estructura de archivos:

Nota: Esta es la barra lateral de mi código de Visual Studio. Estoy usando un tema diferente del estándar y también tengo una extensión que modifica las imágenes de los iconos asociados con cada archivo o carpeta. El nombre que le di a mi proyecto es FAVTVShow .
Lo que es importante saber aquí:
Las carpetas Android e iOS contienen el código nativo generado. Puede ejecutar su aplicación en Android Studio o Xcode abriendo estas carpetas en cada IDE respectivamente. Estas carpetas son importantes para generar la versión de su aplicación.
La carpeta Node_Modules contiene todas las instalaciones del proyecto instaladas por el NPM.
La aplicación se puede editar inicialmente a través del archivo App.js.
El archivo index.js busca y registra el componente global de nuestra aplicación, es decir, el primer componente que se cargará. Importa el contenido del archivo App.js y renderizado en la pantalla.
El archivo Packle.json contiene todos los datos en las instalaciones y también de los scripts relacionados con su proyecto.
Elimine todo el contenido del archivo App.js y reemplácelo con:
import React , { Component } from 'react' ; // 1
import { Text , View , StyleSheet } from 'react-native' ; // 2
// 3
export default class App extends Component {
render ( ) {
return (
// 4
< View style = { styles . hello } >
< Text > Hello, world! </ Text >
</ View >
) ;
}
}
// 5
const styles = StyleSheet . create ( {
hello : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
} ) ;Cuando elimine el contenido de App.js, coloque este nuevo contenido y guarde el archivo, si tiene el simulador en ejecución, recarga automáticamente la vista.
Asegúrese de leer la documentación oficial sobre el texto y ver los componentes y la hoja de estilo Abstraction.
Cambiemos un poco el estilo del texto en el componente de texto . Primero, reescribe la línea de línea de texto para que sea así:
< Text style = {styles.text} > Hello, world! </ Text >Luego agregue el estilo de texto en los estilos . Será así:
const styles = StyleSheet . create ( {
hello : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
text : {
fontSize : 30 ,
color : 'blue' ,
} ,
} ) ;¡Vea el resultado en el simulador cuando guarde el archivo! :)
Necesitamos comenzar a darle una cara a nuestro proyecto de acuerdo con el prototipo. Haremos esto lo más simple posible, al menos inicialmente.
¿Cómo podemos agregar los elementos necesarios de la pantalla de inicio? Uno de ellos es una barra de búsqueda. Hay bibliotecas con este componente listo, pero para que podamos aprender a hacerlo, no las usaremos.
Agregamos el componente TextInput a nuestra segunda línea de importación . Vea la documentación de este componente aquí.
import { Text , View , StyleSheet , TextInput } from 'react-native' ;Modificemos el pasaje del código que se encarga de hacer que la pantalla sea así:
export default class App extends Component {
render ( ) {
return (
< View style = { styles . screen } >
< View style = { styles . search } >
< TextInput style = { styles . input } />
</ View >
< View style = { styles . results } >
< Text > Os resultados aparecerão aqui </ Text >
</ View >
</ View >
) ;
}
}Tenemos un componente de vista que encapsula todos los elementos de la pantalla y recibe el estilo de pantalla .
Dentro de este componente, tenemos otros dos componentes de vista : uno en la parte superior (fondo blanco) que recibe el estilo de búsqueda y otro a continuación (temporalmente gris claro para la visualización) que recibe los resultados .
Dentro del componente superior, tenemos el componente TextView . Y dentro del componente en la parte inferior de la pantalla tenemos el componente de texto .
Ahora modificemos los estilos para que sean así:
const styles = StyleSheet . create ( {
screen : {
flex : 1 ,
flexDirection : 'column' ,
} ,
search : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
input : {
marginTop : 55 ,
height : 40 ,
width : 250 ,
borderColor : 'lightgray' ,
borderWidth : 1 ,
padding : 10 ,
fontSize : 20 ,
} ,
results : {
flex : 4 ,
backgroundColor : 'lightgray' ,
alignItems : 'center' ,
} ,
} ) ;Haga los cambios y guarde el archivo. Ahora vea la explicación para cada elemento:
El componente View que abarca todos los demás componentes (estilo de nombre de pantalla ) tiene FLEX igual a 1. Esto lo hace todo pantalla, ya que abarca a todos los demás. Tiene FlexDirection igual a la columna porque queremos que los componentes dentro de ella se organicen verticalmente.
Tenemos el componente de vista al estilo de búsqueda hacia arriba y los resultados con resultados que permanecen a continuación. Están dentro del componente View con estilo de pantalla y se organizan verticalmente. Tienen que dividir el mismo espacio. Hacemos esto usando el flex. La parte superior tiene FLEX 1 y la parte inferior 4. Esto significa que tenemos 5 partes proporcionales (1+4), que tiene flexión igual a 1 ocupa 1/5 y la flexión igual a 4 ocupa 4/5. IMPORTANTE: Vea la documentación nativa React para obtener más información sobre FlexBox :)
Mirando el componente de vista de estilo de búsqueda , adentro colocamos el componente TextView que se personaliza con el estilo de entrada . Con él, pudimos definir su altura (altura), ancho (ancho), distancia desde el margen superior de la pantalla (marginto), color bordercolor, espesor de ancho de borde, hacia atrás (relleno) y tamaño de fuente de campo (fontizize).
En el simulador, si hace clic en TextInput , el teclado aparece automáticamente. Puede escribir algo y hacer clic en "Regresar" (en el caso de iOS). Por ahora, no sucederá nada porque todavía necesitamos implementar el comportamiento.
Agreguemos una variable llamada estado antes de la función render () que recibirá el texto escrito en el textInput .
state = {
searchText : '' ,
}También cambiaremos TextInput para tener un marcador de posición y para guardarlo en la variable de estado , el texto escrito. Será así:
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
/>Tenga en cuenta el método OnChangetext del componente. Recibe el valor del texto y guardado (this.setState) en SearchText . Podemos verificar esto en tiempo real haciendo un pequeño cambio en otro componente.
Donde tenemos:
< Text > Os resultados aparecerão aqui </ Text >Cambio para:
< Text > {this.state.searchText} </ Text >Guardar y probar para escribir algo en textInput :)
Cambiando un poco más nuestro textInput , usemos el método de submiteding para hacer que la búsqueda ocurra cuando el usuario presiona la tecla de retorno (o equivalente a Android). Por ahora, todavía no presentaremos ninguna solicitud a la API, ¡pero dejaremos las cosas reenviadas!
Nuestro textInput será así:
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
onSubmitEditing = { ( ) => this . submitSearch ( ) }
/>Necesitamos agregar la función SubseCeearch () , esto se puede hacer justo debajo del estado . Será así:
state = {
searchText : '' ,
}
submitSearch ( ) {
alert ( 'Buscar: ' + this . state . searchText ) ;
}Como aún no estamos haciendo la solicitud, puse una alerta para que se dé cuenta de que el contenido escrito en el campo de texto se usará en la búsqueda, ya que ocurrirá dentro de la función SubseCeearch () .
Para que podamos popularizar nuestra aplicación con datos, usemos el laberinto de TV API, que es una API de REST abierta (no necesitamos autenticación), libere y devuelva los datos en formato JSON.
Veamos un ejemplo de búsqueda usando esta API. Si queremos realizar una búsqueda con la palabra anatomía , usaremos el siguiente punto final:
[GET] http://api.tvmaze.com/search/shows?q=anatomy
Como resultado, tendremos el JSON a continuación (solo se muestra un tramo) que contiene todas las entradas que tienen anatomía o algo así como:
[
{
"score" : 20.919525 ,
"show" : {
"id" : 67 ,
"url" : " http://www.tvmaze.com/shows/67/greys-anatomy " ,
"name" : " Grey's Anatomy " ,
"type" : " Scripted " ,
"language" : " English " ,
"genres" : [
" Drama " ,
" Romance " ,
" Medical "
],
"status" : " Running " ,
"runtime" : 60 ,
"premiered" : " 2005-03-27 " ,
"officialSite" : " http://abc.go.com/shows/greys-anatomy/ " ,
"schedule" : {
"time" : " 21:00 " ,
"days" : [
" Thursday "
]
},
"rating" : {
"average" : 8.3
},
"weight" : 99 ,
"network" : {
"id" : 3 ,
"name" : " ABC " ,
"country" : {
"name" : " United States " ,
"code" : " US " ,
"timezone" : " America/New_York "
}
},
"webChannel" : null ,
"externals" : {
"tvrage" : 3741 ,
"thetvdb" : 73762 ,
"imdb" : " tt0413573 "
},
"image" : {
"medium" : " http://static.tvmaze.com/uploads/images/medium_portrait/211/529884.jpg " ,
"original" : " http://static.tvmaze.com/uploads/images/original_untouched/211/529884.jpg "
},
"summary" : " <p>The doctors of Grey Sloan Memorial Hospital deal with life-or-death consequences on a daily basis -- it's in one another that they find comfort, friendship and, at times, more than friendship. Together they're discovering that neither medicine nor relationships can be defined in black and white. Real life only comes in shades of grey.</p> " ,
"updated" : 1576320037 ,
"_links" : {
"self" : {
"href" : " http://api.tvmaze.com/shows/67 "
},
"previousepisode" : {
"href" : " http://api.tvmaze.com/episodes/1749376 "
},
"nextepisode" : {
"href" : " http://api.tvmaze.com/episodes/1760391 "
}
}
}
},
{
"score" : 15.932307 ,
"show" : {
"id" : 34388 ,
"url" : " http://www.tvmaze.com/shows/34388/greys-anatomy-b-team " ,
"name" : " Grey's Anatomy: B-Team " ,
"type" : " Scripted " ,
"language" : " English " ,
"genres" : [
" Drama " ,
" Romance " ,
" Medical "
],
"status" : " Ended " ,
"runtime" : 3 ,
"premiered" : " 2018-01-11 " ,
"officialSite" : " http://abc.go.com/shows/greys-anatomy-b-team " ,
"schedule" : {
"time" : " " ,
"days" : [
" Thursday "
]
},
"rating" : {
"average" : null
},
"weight" : 80 ,
"network" : null ,
"webChannel" : {
"id" : 95 ,
"name" : " ABC.com " ,
"country" : {
"name" : " United States " ,
"code" : " US " ,
"timezone" : " America/New_York "
}
},
"externals" : {
"tvrage" : null ,
"thetvdb" : null ,
"imdb" : null
},
"image" : {
"medium" : " http://static.tvmaze.com/uploads/images/medium_portrait/142/355662.jpg " ,
"original" : " http://static.tvmaze.com/uploads/images/original_untouched/142/355662.jpg "
},
"summary" : " <p>A fresh crop of interns face their first day at Grey Sloan Memorial Hospital. Can these new surgeons survive the pressures of high-stakes medicine, intimidating attendings, and cut throat competition?</p> " ,
"updated" : 1526845476 ,
"_links" : {
"self" : {
"href" : " http://api.tvmaze.com/shows/34388 "
},
"previousepisode" : {
"href" : " http://api.tvmaze.com/episodes/1390266 "
}
}
}
}
]Puede ver una versión más amigable del contenido de este JSON usando el editor JSON en línea. ¡Me he quedado guardado para que puedas verlo todo! Haga clic aquí ;)
En JSON, el editor en línea fue fácil de ver que es una matriz con 9 objetos y cada objeto es una serie.
Según el prototipo y lo que hemos implementado hasta ahora:
Pongamos esto en práctica en la siguiente sección usando Axios.
Necesitamos instalar la biblioteca Axios en el proyecto. Haremos esto escribiendo el siguiente comando en el terminal:
$ npm install axiosDespués de eso, creemos una carpeta de servicio y un archivo API.JS dentro de él. Ponamos el siguiente código en el archivo:
import axios from 'axios' ; // 1
// 2
const api = axios . create ( {
baseURL : 'http://api.tvmaze.com/' ,
} ) ;
export default api ;En App.js , importemos el archivo API.JS :
import api from './service/api' ;Y modificemos la función SubseCeearch () para que sea así:
submitSearch = async ( ) => { // 1
if ( this . state . searchText != '' ) { // 2
try { // 3
const response = await api . get ( '/search/shows' , { // 4
params : { q : this . state . searchText } // 5
} ) ;
alert ( JSON . stringify ( response ) ) ;
} catch ( error ) {
alert ( JSON . stringify ( error ) ) ;
}
}
}Alertas dentro del bloque de try y dentro del bloque de captura serán útiles para ver las respuestas obtenidas en la solicitud. En otro momento, usaremos estas respuestas de otra manera :)
Vea más sobre las funciones asincrónicas aquí y sobre las promesas aquí.
Comencemos a implementar FlatList para mostrar la lista de resultados de búsqueda. Modificemos nuestra importación para esto:
import { Text , View , StyleSheet , TextInput , FlatList } from 'react-native' ;Luego modificaremos el estado y la función SubseCeearch () para que sean:
state = {
searchText : '' ,
searchResults : null , // 1
}
submitSearch = async ( ) => {
if ( this . state . searchText != '' ) {
try {
const response = await api . get ( '/search/shows' , {
params : { q : this . state . searchText } ,
} ) ;
this . setState ( { searchResults : response . data } ) ; // 2
} catch ( error ) {
alert ( JSON . stringify ( error ) ) ;
}
}
}También tenemos que modificar el render () , insertando la lista plana en ella:
render ( ) {
return (
< View style = { styles . screen } >
< View style = { styles . search } >
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
onSubmitEditing = { ( ) => this . submitSearch ( ) }
/>
</ View >
< View style = { styles . results } >
< FlatList
data = { this . state . searchResults }
renderItem = { ( { item } ) => < Text > { item . show . name } </ Text > }
keyExtractor = { item => item . show . id }
/>
</ View >
</ View >
) ;
}Tenga en cuenta que estamos representando solo el nombre de la serie con el componente de texto . Sin embargo, creemos nuestra tarjeta aquí, según la Sección 1.3.
En un proyecto, posiblemente crearemos más de un componente. Para facilitar la organización, creemos una carpeta de componentes y todos los componentes que creamos se guardarán en ella.
Dentro de esta carpeta, crearemos un archivo llamado Card.js con el siguiente contenido:
import React , { Component } from 'react' ;
import { Text , View , TouchableOpacity , Image , StyleSheet } from 'react-native' ;
export default class Card extends Component {
render ( ) {
return (
< TouchableOpacity style = { styles . container } >
< View style = { styles . cardView } >
< View >
< Image
style = { styles . image }
source = { { uri : this . props . info . image == null ? 'https://i.ibb.co/YfZFr7k/noimg.png' : ( this . props . info . image . original || this . props . info . image . medium ) } }
/>
</ View >
< View style = { { flexDirection : 'column' } } >
< Text style = { styles . name } > { this . props . info . name || 'Sem nome' } </ Text >
< Text style = { styles . genres } > { this . props . info . genres || 'Sem gênero' } </ Text >
</ View >
</ View >
</ TouchableOpacity >
) ;
}
}
const styles = StyleSheet . create ( {
container : {
padding : 10 ,
} ,
cardView : {
alignItems : 'center' ,
flexDirection : 'row' ,
} ,
image : {
width : 80 ,
height : 120 ,
resizeMode : 'contain' ,
} ,
name : {
fontSize : 20 ,
marginLeft : 10 ,
} ,
genres : {
fontSize : 16 ,
marginLeft : 10 ,
} ,
} ) ;Tenga en cuenta que el nombre del componente es tarjeta y que utilicé una imagen para servir como marcador de posición si la serie no tiene una URL válida.
Ahora importemos nuestro nuevo componente en el archivo App.js :
import Card from './components/card' ;Y en Flatlist reemplazaremos el contenido actual con:
< FlatList
data = { this . state . searchResults }
renderItem = { ( { item } ) => < Card info = { item . show } /> }
keyExtractor = { item => item . show . id }
/>En lugar de usar el componente de texto , ahora estamos usando la tarjeta y la pasamos por el atributo de información que recibe el objeto Show .
Consulte el archivo Card.js que usamos varias veces la expresión this.props.info para acceder a los valores que se pasaron cuando se usa el componente. Para obtener el nombre de la serie, usamos esto.props.info.name , por ejemplo.