이 튜토리얼의 목적은 React Native의 첫 단계에서 귀하를 안내하는 것입니다.
TV Maze API를 사용하여 앱을 구축하고 아래 프로토 타입을 따르겠습니다.

이 튜토리얼은 건설 중입니다. 지금까지 그는 다음과 같은 점을 다룹니다.
건설중인 코드 준비가있는 저장소 : https://github.com/erbuen/favtvshow :)
코드를 작성하기 전에 각 화면과 관련된 동작을 이해하는 것이 중요합니다.
이것은 응용 프로그램을 시작할 때 사용자가 볼 화면입니다.

그녀는 검색 바와 바의 오른쪽에 버튼이 있어야합니다.
검색 창에는 자리 표시자가 있어야합니다. 원하는 단어를 입력 할 때는 키보드가 검색을 시작할 수있는 버튼을 사용해야합니다. 예를 들어 모바일 브라우저에서 URL을 입력 할 때 발생하는 방법과 같이 검색을 시작합니다.
결과 찾기는 검색 바 아래와 제목 "검색 결과"아래에 하나씩 표시해야합니다. 결과를 얻지 못하면 "결과가 없음"메시지를 표시해야합니다.
결과는 이미지, 시리즈의 이름 및 그에 따른 장르를 포함하는 "카드"로 표시해야합니다 (섹션 1.3 참조).
사용자가 결과 중 하나를 선택하면 시리즈의 전체 정보를 표시하는 다른 화면으로 가져와야합니다. 곧이 화면을 설명하겠습니다.
검색 창의 오른쪽 버튼은 클릭하면 "즐겨 찾기"라는 제목 아래에있는 사용자의 가장 좋아하는 시리즈를 표시해야합니다.
검색이 진행중인 경우 화면에 아무것도 표시하지 마십시오.
좋아하는 시리즈가 없다면 "당신은 여전히 좋아하는 시리즈가 없습니다"라는 메시지를 표시하십시오.
사용자가 검색 결과 또는 유리한 시리즈를 클릭하면이 화면으로 가져 가야합니다.

이 화면에는 시리즈, 이름, 장르 및 요약과 관련된 이미지가 표시되어야합니다.
이름과 장르 옆에 사용자가 시리즈를 선호 할 수 있도록 버튼이 있어야합니다.
사용자가 시리즈를 선호하기 위해 버튼을 클릭하면 응용 프로그램의 내부 글로벌 스토리지에 데이터를 저장해야하며 "토스트"또는 이와 유사한 사용자에게 시각적으로 반환해야합니다.
시리즈의 이미지 위에는 이전 화면으로 이동하는 리턴 버튼이 있어야합니다.
요약의 내용이 장치의 화면 크기보다 클 수 있으므로 사용자는 화면을 굴릴 수 있어야합니다.
검색하고 하나 이상의 결과를 얻거나 좋아하는 시리즈에 액세스 할 때 시리즈 목록이 표시됩니다.
이를 위해 아래 이미지로 카드 구성 요소를 작성해야합니다.

카드를 클릭하고 플랫리스트에 표시해야합니다.
프로젝트를 시작할 시간이 왔습니다! 이렇게하려면 React Native Page를 방문하여 시작을 클릭하십시오.

시작 페이지에서 React Native로 시작하는 데 필요한 모든 정보를 찾을 수 있습니다. 이 튜토리얼의 경우 React Native ClickStart 옵션을 선택하는 것이 좋습니다.

그런 다음 프로필에 맞는 최상의 옵션을 선택하십시오. 내 경우에는 Mac을 사용하여 개발하므로 개발 중에는 IPhone 을 사용하여 테스트 할 때 Target 에서 iOS를 iOS 로 선택했지만 Android를 선택할 수있었습니다.

Mac을 사용하는 경우 IOS 로만 Target을 선택할 수 있습니다. Windows 및 Linux 의 경우 반드시 Android를 선택해야합니다.
운영 체제에 따라 옵션을 선택한 후 React Native를 사용하는 데 필요한 시설을 설치하려는 지침을 따르십시오.
React Native 사이트의 단계별에 따라 모든 종속성 설치를 완료하면 다음 명령으로 프로젝트를 부팅 할 수 있습니다.
npx react-native init NomeDoProjeto프로젝트의 생성은 몇 분이 걸릴 수 있습니다. 걱정하지 말고 터미널을 통한 로그를 따르십시오 :)
프로세스가 완료되면 다음 명령으로 프로젝트를 실행할 수 있습니다.
cd NomeDoProjeto
npx react-native run-iosMacOS를 사용하는 경우. 또는 Windows 또는 Linux를 사용하는 경우 :
cd NomeDoProjeto
npx react-native run-android잠시 후 - 우리가 처음 실행하면이 명령을 실행하는 데 실제로 오랜 시간이 걸릴 수 있습니다. 대상 OS 에 따라 다음과 같은 것을 볼 수 있습니다.

중요 : 첫 번째 실행 (변경 사항 없음)의 기본 프로젝트 텍스트는 변경 사항 (Reload)을보고 디버그 할 수있는 옵션을 언급합니다. 즉, 코드를 변경하고 변경 사항을보고 디버그를 실시간으로 만들 수 있습니다.
프로젝트를 수정하려면 선택한 코드 편집기를 사용해야합니다.
선택한 코드 편집기에서 프로젝트를 열 때이 폴더와 파일 구조가 표시됩니다.

참고 : 이것은 Visual Studio Code의 사이드 바입니다. 표준과 다른 테마를 사용하고 있으며 각 파일 또는 폴더와 관련된 아이콘의 이미지를 수정하는 확장 기능이 있습니다. 내가 프로젝트에 준 이름은 favtvshow 입니다.
여기서 알아야 할 사항 :
Android 및 iOS 폴더에는 생성 된 기본 코드가 포함되어 있습니다. Android Studio 또는 Xcode에서 각각 각 IDE에서 이러한 폴더를 열면 응용 프로그램을 실행할 수 있습니다. 이 폴더는 응용 프로그램의 출시를 생성하는 데 중요합니다.
node_modules 폴더에는 NPM에서 설치 한 모든 프로젝트 시설이 포함되어 있습니다.
응용 프로그램은 처음에 app.js 파일을 통해 편집 할 수 있습니다.
index.js 파일은 응용 프로그램의 전역 구성 요소, 즉로드 할 첫 번째 구성 요소를 찾고 기록합니다. app.js 파일의 내용이 중요하고 화면에서 렌더링됩니다.
package.json 파일에는 구내의 모든 데이터와 프로젝트와 관련된 스크립트가 포함되어 있습니다.
app.js 파일의 모든 내용을 삭제하고 다음으로 바꾸십시오.
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' ,
} ,
} ) ;app.js 컨텐츠를 제거하면이 새 컨텐츠를 넣고 파일을 저장하십시오. 시뮬레이터가 실행중인 경우 자동으로 뷰가 재충전됩니다.
텍스트 및 뷰 구성 요소 및 추상화 스타일 시트에 대한 공식 문서를 읽으십시오.
텍스트 구성 요소에서 텍스트 스타일을 조금 변경합시다. 먼저, 텍스트 줄 라인을 다시 작성하여 다음과 같습니다.
< Text style = {styles.text} > Hello, world! </ Text >그런 다음 스타일 로 텍스트 스타일을 추가하십시오. 다음과 같습니다.
const styles = StyleSheet . create ( {
hello : {
flex : 1 ,
justifyContent : 'center' ,
alignItems : 'center' ,
} ,
text : {
fontSize : 30 ,
color : 'blue' ,
} ,
} ) ;파일을 저장할 때 시뮬레이터에서 결과를 확인하십시오! :)
프로토 타입에 따라 프로젝트에 얼굴을주기 시작해야합니다. 우리는 최소한 초기에 가능한 한 간단 하게이 일을 할 것입니다.
홈 화면의 필요한 요소를 어떻게 추가 할 수 있습니까? 그들 중 하나는 검색 창입니다. 이 준비된 구성 요소가있는 라이브러리가 있지만이를 수행하는 방법을 배울 수 있도록 사용하지 않을 것입니다.
TextInput 구성 요소를 두 번째 가져 오기 라인에 추가하겠습니다. 이 구성 요소의 문서를 여기에서 참조하십시오.
import { Text , View , StyleSheet , TextInput } from 'react-native' ;화면 렌더링을 처리하는 코드 구절을 수정하겠습니다.
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 >
) ;
}
}화면의 모든 요소를 캡슐화하고 화면 스타일을 수신하는 보기 구성 요소가 있습니다.
이 구성 요소에는 검색 스타일을 수신하는 상단 (흰색 배경)과 결과를 수신하는 아래 (일시적으로 밝은 회색)의 두 가지 다른 뷰 구성 요소가 있습니다.
최상위 구성 요소에는 TextView 구성 요소가 있습니다. 화면 하단의 구성 요소 내부에 텍스트 구성 요소가 있습니다.
이제 스타일을 수정하여 다음과 같은 방식으로 수정합시다.
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' ,
} ,
} ) ;변경하고 파일을 저장하십시오. 이제 각 항목에 대한 설명을 참조하십시오.
다른 모든 구성 요소 ( 스크린 이름 스타일)를 포함하는 보기 구성 요소는 1과 동일합니다. 이는 다른 모든 것을 포함하므로 모든 화면을 만듭니다. 수직으로 구성된 구성 요소가 수직 으로 구성되기 때문에 FlexDirection이 열과 같습니다.
검색 -스타일 보기 구성 요소가 위로 향하고 결과가 아래에 유지되는 결과 가 있습니다. 화면 스타일로 보기 구성 요소 내부에 있으며 수직으로 구성됩니다. 그들은 같은 공간을 나누어야합니다. 우리는 Flex를 사용하여 이것을합니다. 상단에는 플렉스 1과 하단 4가 있습니다. 이는 5 개의 비례 부품 (1+4)을 가지고 있으며, 이는 1과 같은 플렉스가 1/5를 차지하고 플렉스는 4/5를 차지합니다. 중요 : Flexbox에 대해 자세히 알아 보려면 React Native Documentation을 참조하십시오 :)
검색 스타일 보기 구성 요소를 살펴보면 내부에 입력 스타일로 사용자 정의 된 TextView 구성 요소를 넣습니다. 그것으로, 우리는 높이 (높이), 너비 (너비), 화면의 상단 여백 (Margintop), Bordercolor 색상, Borderwidth 두께, 뒤로 (패드) 및 필드 소스 크기 (fontsize)를 정의 할 수있었습니다.
시뮬레이터에서 TextInput을 클릭하면 키보드가 자동으로 나타납니다. 무언가를 입력하고 "반환"을 클릭 할 수 있습니다 (iOS의 경우). 지금은 우리가 여전히 행동을 구현해야하기 때문에 아무 일도 일어나지 않을 것입니다.
TextInput 에 입력 된 텍스트를 수신 할 렌더 () 함수 전에 state 라는 변수를 추가하겠습니다.
state = {
searchText : '' ,
}또한 자리 표시자를 갖도록 TextInput을 변경하고 유형 텍스트의 상태 변수에 저장합니다. 그는 다음과 같을 것입니다.
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
/>구성 요소의 onchangetext 메소드에 유의하십시오. SearchText 에서 텍스트 의 값을 받고 저장 (this.setstate). 우리는 이것을 실시간으로 확인하면 다른 구성 요소를 약간 변경할 수 있습니다.
우리가 가진 곳 :
< Text > Os resultados aparecerão aqui </ Text >변경 사항 :
< Text > {this.state.searchText} </ Text >텍스트 에 무언가를 입력하기 위해 저장하고 테스트하십시오 :)
텍스트를 조금 더 변경하면 사용자가 리턴 키를 누르면 (또는 Android에서 해당)를 누를 때 onsubmitediting 메소드를 사용하여 검색이 발생하도록합시다. 지금은 아직 API에 요청하지는 않지만 물건을 전달할 것입니다!
우리의 텍스트는 다음과 같습니다.
< TextInput
placeholder = { 'Procure uma série' }
style = { styles . input }
onChangeText = { ( text ) => this . setState ( { searchText : text } ) }
onSubmitEditing = { ( ) => this . submitSearch ( ) }
/>submitsearch () 함수를 추가해야합니다. 이는 상태 바로 아래에서 수행 할 수 있습니다. 다음과 같습니다.
state = {
searchText : '' ,
}
submitSearch ( ) {
alert ( 'Buscar: ' + this . state . searchText ) ;
}아직 요청을하지 않으므로 텍스트 필드에 입력 된 콘텐츠가 Submitsearch () 함수 내에서 발생하므로 검색에 사용되도록 알 수 있도록 경고를 표시합니다.
우리는 데이터로 앱을 대중화 할 수 있도록 Open REST API (인증 할 필요가 없음) 인 API TV 미로를 사용하고 무료로 JSON 형식으로 데이터를 반환합시다.
이 API를 사용하여 검색 예제를 살펴 보겠습니다. 해부학이라는 단어로 검색을 수행하려면 다음 엔드 포인트를 사용합니다.
[GET] http://api.tvmaze.com/search/shows?q=anatomy
결과적으로, 우리는 아래에 JSON을두고 해부학이 있는 모든 항목을 포함하는 (하나의 스트레치 만 표시됩니다) :
[
{
"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 "
}
}
}
}
]JSON 편집기 온라인을 사용 하여이 JSON의 컨텐츠의 친근한 버전을 볼 수 있습니다. 나는 당신이 모든 것을 볼 수 있도록 저장을 남겼습니다! 여기를 클릭하십시오;)
JSON 편집기에서 온라인에서는 9 개의 객체가있는 배열이고 각 객체가 시리즈라는 것을 쉽게 알 수있었습니다.
프로토 타입과 지금까지 구현 한 내용에 따르면 :
이것을 Axios를 사용하여 다음 섹션에서 실천하겠습니다.
프로젝트에 Axios 라이브러리를 설치해야합니다. 터미널에서 다음 명령을 입력하여이를 수행합니다.
$ npm install axios그런 다음 서비스 폴더와 API.JS 파일을 만들어 봅시다. 다음 코드를 파일에 넣으십시오.
import axios from 'axios' ; // 1
// 2
const api = axios . create ( {
baseURL : 'http://api.tvmaze.com/' ,
} ) ;
export default api ;app.js 에서 API.JS 파일을 가져 오겠습니다.
import api from './service/api' ;그리고 submitsearch function ()을 다음과 같이 수정합시다.
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 ) ) ;
}
}
}시도 블록 내부와 캐치 블록 내부의 경고는 요청에서 얻은 답변을 보는 데 유용합니다. 다른 시간에, 우리는이 답변을 다른 방식으로 사용할 것입니다 :)
비동기 기능에 대한 자세한 내용은 여기와 약속에 대한 자세한 내용을 참조하십시오.
검색 결과 목록을 표시하려면 Flatlist 구현을 시작하겠습니다. 이를 위해 가져 오기를 수정합시다.
import { Text , View , StyleSheet , TextInput , FlatList } from 'react-native' ;그런 다음 상태 와 submitsearch () 함수를 수정하여 다음과 같이 수정합니다.
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 ) ) ;
}
}
}또한 렌더 ()을 수정하고 플랫리스트 를 삽입해야합니다.
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 >
) ;
}텍스트 구성 요소가있는 시리즈의 이름 만 렌더링하고 있습니다. 그러나 섹션 1.3에 따라 여기에서 카드 유형을 만들어 봅시다.
프로젝트에서는 둘 이상의 구성 요소를 만들 것입니다. 조직을 용이하게하기 위해 구성 요소 폴더를 만들고 우리가 만든 모든 구성 요소가 저장 될 것입니다.
이 폴더 내에서 다음 내용이있는 card.js 라는 파일을 만듭니다.
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 ,
} ,
} ) ;구성 요소의 이름은 카드 이며 시리즈에 유효한 URL이없는 경우 자리 표시 자 역할을하기 위해 이미지를 사용했습니다.
이제 새 구성 요소를 app.js 파일로 가져 오겠습니다.
import Card from './components/card' ;플랫리스트 에서는 현재 내용을 다음과 같이 대체합니다.
< FlatList
data = { this . state . searchResults }
renderItem = { ( { item } ) => < Card info = { item . show } /> }
keyExtractor = { item => item . show . id }
/>텍스트 구성 요소를 사용하는 대신 이제 카드를 사용하고 있으며 표시 객체를 수신하는 정보 속성을 통해 전달 합니다.
구성 요소를 사용할 때 전달 된 값에 액세스하기 위해 this.props.info 표현식을 여러 번 사용하는 Card.js 파일을 참조하십시오. 시리즈의 이름을 얻으려면 예를 들어 this.props.info.name을 사용합니다.