Workshop
การนำโปรเจคที่เสร็จสมบูรณ์ไปใช้งาน
- ใช้คำสั่ง
clone https://github.com/JcsnP/PokemonApp.git
ใน Terminal - ใช้คำสั่ง
cd PokemonApp
เพื่อเข้าไปยังโฟลเดอร์โปรเจค - ใช้คำสั่ง
npm install
เพื่อติดตั้งแพคเกจ - ใช้คำสั่ง
npx expo start
เพื่อรันโปรเจค
npx create-expo-app PokemonApp
axios
npm i axios
pokemon
npm i pokemon
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View ,SafeAreaView} from 'react-native';
import Main from './src/Main';
export default function App() {
return (
<>
<StatusBar />
<Main/>
</>
);
}
import { View, Text, TextInput, SafeAreaView, Alert, StyleSheet, ActivityIndicator, Button, placeholder, Image, TouchableOpacity, StatusBar, Keyboard } from 'react-native'
import React, { Component } from 'react';
import pokemon from 'pokemon';
import axios from 'axios';
import Pokemon from './components/Pokemon';
const POKE_API_URL = 'https://pokeapi.co/api/v2';
export default class Main extends Component {
constructor(props) {
super(props)
this.state={
isLoading:false,
searchInput:'',
name:'',
pic:'',
types:[],
desc:'',
}
}
render() {
}
}
const{ name,pic,types,desc,searchInput,isLoading } = this.state
return (
<SafeAreaView style={styles.wrapper}>
<View style={styles.container}>
<Image style={styles.image} source={{uri: 'https://user-images.githubusercontent.com/37466531/202855683-08bb0351-2ac9-486c-8424-9e68b8f71ece.png'}} />
<View style={styles.headContainer}>
<View style={styles.textInpuTContainer}>
<TextInput style={styles.textInput}
placeholder='Pokemon Name'
onChangeText={(searchInput)=> this.setState({searchInput})}
onSubmitEditing={this.searchPokemon}
value={this.state.searchInput}
clearButtonMode="always"
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.searchButton}
onPress={this.searchPokemon}
>
<Text style={{ color: "white", fontWeight: 'bold', fontSize: 19 }}>SEARCH</Text>
</TouchableOpacity>
</View>
</View>
<View style={styles.mainContainer}>
{isLoading && <ActivityIndicator size="large" color="green"/>}
{!isLoading && (
<Pokemon name={name} pic={pic} types={types} desc={desc}/>
)}
</View>
</View>
</SafeAreaView>
);
searchPokemon = async()=>{
try{
// ซ่อน keyboard หลังจากผู้ใช้กดปุ่มค้นหา
Keyboard.dismiss()
// รับไอดีของโปเกมอนตัวนั้นมาจากชื่อที่กรอกไปใน testInput
const pokemonID = pokemon.getId((this.state.searchInput.charAt(0).toUpperCase() + this.state.searchInput.slice(1)))
this.setState({isLoading:true})
//ยิงget request
const { data: pokemonData} = await axios.get(`${POKE_API_URL}/pokemon/${pokemonID}`)
//เข้าถึงApiไปยังpathpokemonละดึงIDมา
const { data: pokemonSpecieData} = await axios.get(`${POKE_API_URL}/pokemon-species/${pokemonID}`)
//ดึงข้อมูล DATA
const { name, sprites, types}= pokemonData
const { flavor_text_entries }= pokemonSpecieData
this.setState({
name,
pic : sprites.front_default,
types: this.getTypes(types),
desc: this.getDescription(flavor_text_entries),
isLoading: false
})
}catch(err){
Alert.alert('ข้อผิดพลาด','ไม่พบข้อมูล POKEMON ดังกล่าว');
}
}
getTypes = (types)=> types.map(({slot,type}) => ({
id:slot,
name: type.name
}))
getDescription = (entries) => entries.find((item)=>item.language.name === 'en').flavor_text;
const styles = StyleSheet.create({
wrapper: {
flex:1,
},
container: {
flex:1,
padding:20,
backgroundColor:'#FFF'
},
headContainer:{
display: 'flex',
flexDirection:'row',
marginTop:20,
},
textInpuTContainer:{
flex:2
},
buttonContainer:{
flex:1
},
mainContainer:{
flex:9
},
textInput:{
height:35,
marginBottom:10,
borderColor:'#ccc',
borderWidth:1,
backgroundColor:'#eaeaea',
padding:5,
borderRadius: 7,
},
image:{
width:100,
height:100,
alignSelf: 'center'
},
searchButton: {
borderRadius: 5,
padding: 6,
backgroundColor: "#3682FF",
width: "96%",
alignItems: "center",
color: "white",
fontWeight: 'bold',
marginHorizontal: 4
},
})
import { View, Text , Image,StyleSheet } from 'react-native'
import React from 'react'
export default Pokemon = ({name,pic, types, desc})=>{
// ทำให้รายละเอียดเปลี่ยนจากหลายบรรทัดเป็นบรรทัดเดียว
desc = desc.replace(/\n/g, ' ')
return(
<View style={styles.mainDetails}>
<Image style={styles.image} source={{uri: pic.length === 0 ? undefined : pic}} resizeMode="contain" />
<Text style={styles.name}>{name.charAt(0).toUpperCase() + name.slice(1)}</Text>
<View style={styles.typesContainer}>
{
types.map((item, key) => (
<View style={[styles[item.name],styles.type]} key={key}>
<Text style={styles.typeText}>{item.name.charAt(0).toUpperCase() + item.name.slice(1)}</Text>
</View>
))
}
</View>
<View style={styles.description}>
<Text style={styles.descriptionText}>
{desc}
</Text>
</View>
</View>
);
}
//style ตกเเต่งหน้าPokemon
const styles = StyleSheet.create({
mainDetails:{
width: '100%',
height: '100%',
alignSelf: 'center',
backgroundColor: '#F7F7F7',
borderRadius: 7,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 2,
},
image:{
marginTop: 10,
width:210,
height:210,
alignSelf: 'center'
},
name:{
fontSize:30,
fontWeight:'bold',
textAlign:'center'
},
typesContainer: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-evenly'
},
type:{
padding: 5,
width: '40%',
alignItems:'center',
marginVertical: 14,
borderRadius: 3,
},
typeText:{
color:'white',
fontWeight:'bold',
fontSize:20
},
description:{
paddingHorizontal: 30,
marginTop: 15
},
descriptionText: {
textAlign: 'justify',
fontSize: 18,
fontWeight: 'bold',
},
normal:{
backgroundColor:'#A8A878'
},
fire:{
backgroundColor:'#f08030'
},
water:{
backgroundColor:'#6890f0'
},
electric:{
backgroundColor:"#f8d030",
},
grass:{
backgroundColor:'#78c850'
},
ice:{
backgroundColor:'#98d8d8'
},
fighting:{
backgroundColor:'#c03028'
},
poison:{
backgroundColor:'#a04028'
},
ground:{
backgroundColor:'#e9c968'
},
flying:{
backgroundColor:'#a890f0'
},
psychic:{
backgroundColor:'#f85888'
},
bug:{
backgroundColor:'#a85800'
},
rock:{
backgroundColor:'#b8a038'
},
ghost:{
backgroundColor:'#705898'
},
dragon:{
backgroundColor:'#7038f8'
},
dark:{
backgroundColor:'#705848'
},
steel:{
backgroundColor:'#b8b8d0'
},
fairy:{
backgroundColor:'#e898e8'
}
});
pokemon-npm https://www.npmjs.com/package/pokemon
axios-npm https://www.npmjs.com/package/axios
สอน React Native สร้างแอป Pokemon Search https://youtu.be/QvkjcWhuHEQ