일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 폴더구조
- ReactNative
- React Natvive
- 티스토리챌린지
- React Native
- Project Bee
- 원복
- 구현
- Navigation
- 비트마스킹
- BFS
- 완전탐색
- 버튼 활성화
- 해외 대외활동
- 이영직
- 노마드코더
- 상속 관계 매핑
- 창의충전소
- web view
- multipart upload
- 자료구조
- 경우의 수
- FlatList
- bfs dfs
- react
- 백준 1992
- springboot
- 휴대폰 기기
- service 테스트
- 오블완
- Today
- Total
유미의 기록들
[React Native -15] 행정안전부 주소 API 사용하여 직접 구현해보기 본문
이전에는 다음 주소 API를 사용하기 위해 라이브러리를 설치하여 쉽게 구현할 수 있었다
하지만, API를 사용하는 법을 제대로 습득하고, 디자인에 대한 자율성을 주고자 행정안전부에서 제공하는 도로명 주소 오픈 API를 사용해서 직접 구현해보기로 하였다
https://business.juso.go.kr/addrlink/openApi/searchApi.do
1. 승인키 발급받기
승인키는 도로명주소 개발자센터 페이지에서 신청하여 실시간으로 발급 가능하다
2. 승인키 적용방법
행안부 도로명 주소 API는 URL 형태로 제공되며, API요청 URL을 호출하기 위해서는 발급받은 승인키와 필요한 요청변수를 입력해야 한다
우리는 검색 API를 사용할 것이다
이렇게 발급받은 승인키와 필요한 요청변수를 입력을 하고 API요청 URL을 호출하면
https://business.juso.go.kr/addrlink/addrLinkApi.do?confmKey=승인키¤tPage=1&countPerPage=5&keyword=삼성동&resultType=json
요청한 값들에 대한 데이터가 json형태로 불러온다
구현할 때 내가 필요한 정보는 common의 totalCount와 juso의 zipNo, readAddr, jibunAddr이다
React Native에서 구현해보면,,,,
import React, { Component, PureComponent } from 'react';
import { View, Text, TextInput, TouchableOpacity, FlatList,Keyboard,Modal} from 'react-native';
import { styles } from "../../styles/address_search";
import Icon from 'react-native-vector-icons/MaterialIcons';
import EmptyIcon from 'react-native-vector-icons/SimpleLineIcons';
import PageIcon from 'react-native-vector-icons/AntDesign'
import WebServiceManager from '../../util/webservice_manager';
import Indicator from '../../util/indicator';
class SearchAddress extends Component {
constructor(props) {
super(props);
this.state = {
addressContents:[],
commonContents:[],
searchText: "",
searchViewVisible:false,
emptyListViewVisible:false,
page:1,
totalCount:0,
indicator:false,
}
}
//검색 버튼을 눌렀을 때
searchAddress=()=>{
if(this.state.searchText == "")
{
alert("주소를 입력해주세요");
}
else{
this.setState({page:1},()=>this.goGetAddress(this.state.page))
this.setState({searchViewVisible:true});
Keyboard.dismiss();
}
}
goGetAddress=(page)=>{
this.setState({indicator:true})
this.callGetAddressAPI(page).then((response) => {
this.setState({ addressContents: response.results.juso,commonContents: response.results.common,totalCount:response.results.common.totalCount,indicator:false,emptyListViewVisible:false }
,()=>{
if(this.state.addressContents.length==0){
this.setState({emptyListViewVisible:true})
}
});
//console.log('componentResponse',response)
});
}
//페이지 감소 버튼 클릭
pageDownClicked=()=>{
if (this.state.page > 1)
this.setState({ page: this.state.page - 1 },()=>this.goGetAddress(this.state.page))
}
//페이지 증가 버튼 클릭
pageUpClicked=()=>{
if (this.state.page < (this.state.totalCount / 4))
this.setState({ page: this.state.page + 1 },()=>this.goGetAddress(this.state.page))
}
async callGetAddressAPI(page) {
let manager = new WebServiceManager("https://business.juso.go.kr/addrlink/addrLinkApi.do?confmKey=승인키¤tPage=" + page + "&countPerPage=4&keyword=" + this.state.searchText + "&resultType=json");
let response = await manager.start();
if (response.ok)
return response.json();
else
Promise.reject(response);
}
render() {
return (
<View style={styles.total_container}>
<View style={styles.search_view}>
<View style={styles.search_input}>
<View style={styles.row_layout}>
<TextInput style={styles.input}
onChangeText={(text) => this.setState({ searchText: text })}
onEndEditing={this.searchAddress }
placeholder="도로명 또는 지번을 입력하세요"
placeholderTextColor="light grey" />
<TouchableOpacity style={styles.search_btn} onPress={this.searchAddress}>
<Icon name="search" size={30} color="light grey" />
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles.content_view}>
<Modal transparent={true} visible={this.state.indicator}>
<Indicator />
</Modal>
{this.state.emptyListViewVisible && <>
<View style={{justifyContent:'center',alignItems:'center',paddingTop:'5%'}}>
<EmptyIcon name="exclamation" size={40} color="#D1D1D1" />
<Text style={{marginTop:'5%'}}>검색 결과가 없습니다</Text>
</View>
</>}
{this.state.searchViewVisible?
<FlatList
data={this.state.addressContents}
renderItem={({item,index})=><AddressItem item={item} navigation={this.props.navigation} addressListener={this.props.route.params.addressListener}/>}/> :
<>
<Text style={styles.title}>TIP</Text>
<Text style={styles.text}>도로명, 건물명, 지번 중 선택하여</Text>
<Text style={styles.text2}>입력하세요 </Text>
<Text style={styles.content}> 도로명 + 건물번호 <Text style={styles.content2}> 예) 테헤란로 152</Text></Text>
<Text style={styles.content}> 동/읍/면/리 + 번지 <Text style={styles.content2}> 예) 역삼동 737</Text> </Text>
<Text style={styles.content}> 건물명, 아파트명 <Text style={styles.content2}> 예) 삼성동 힐스테이트</Text></Text>
</>}
</View>
{this.state.searchViewVisible&&this.state.emptyListViewVisible==false&&
<View style={styles.page_view}>
<View style={styles.row_layout}>
<TouchableOpacity onPress={this.pageDownClicked} activeOpacity={0.8} >
<PageIcon name="leftsquareo" size={30} color="light grey" />
</TouchableOpacity>
<Text style={styles.text}> <Text style={[styles.text,{color:'blue'}]}>{this.state.page} </Text> / {Math.ceil(this.state.totalCount/4)} </Text>
<TouchableOpacity onPress={this.pageUpClicked} activeOpacity={0.8}>
<PageIcon name="rightsquareo" size={30} color="light grey" />
</TouchableOpacity>
</View>
</View>}
</View>
);
}
}
✔️ 검색버튼을 누를 시, 주소검색 API호출해서 addressContents와 commonContents 배열에 넣는다
* 이때 page는 1으로 초기화시켜준다
✔️ addressContents가 빈 배열이면 (즉, 검색결과를 불러올 수 없으면) emptyListViewVisible을 true로 setState해주어서 검색결과가 표시되지 않는다는 View를 보여준다
✔️ 증가, 감소 버튼을 클릭할 때 마다 page를 setState해준다
addressContents 배열값에 들어있는 Data를 뿌려주는 부분 (zipNo, roadAddr, jibunAddr 사용)
class AddressItem extends PureComponent{
constructor(props) {
super(props);
}
addressItemClicked=(zipNo,roadAddr)=>{
this.props.navigation.navigate('Payment');
this.props.addressListener(zipNo, roadAddr);
}
render(){
const { zipNo,roadAddr,jibunAddr } = this.props.item;
return(
<TouchableOpacity activeOpacity={0.8} onPress={()=>this.addressItemClicked(zipNo,roadAddr)}>
<View style={styles.outputStyle}>
<View style={styles.row_layout}>
<View style={styles.titleLayout}>
<View style={styles.flex}><Text>도로명</Text></View >
<View style={styles.flex}><Text>지번</Text></View >
</View>
<View style={styles.addressLayout}>
<View style={styles.flex}><Text style={{ color: "black" }}>{roadAddr} </Text></View >
<View style={styles.flex}><Text style={{ color: "black" }}>{jibunAddr}</Text></View >
</View>
<View style={styles.numberLayout}>
<Text style={[styles.text,{fontWeight:'600'}]}>{zipNo}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
}
}
➕ 추가로 알게 된부분
✔️ TextInput에서 onChangeText 는 텍스트가 바뀔 때 마다 함수를 호출하였는데 onEndEditing을 사용하면 입력이 끝났을 때 함수를 호출한다
onEndEditing={() => this.setState({value: this.state.searchText}) }
✔️ 하위 클래스에서 navigation을 사용할 때는 props로 전달해주어야 한다
{this.state.modal == true && (<SearchView searchText={this.state.value} navigation={this.props.navigation}/>)}
'MDLAB 기록 > 차량부품거래애플리케이션' 카테고리의 다른 글
[React Native -17] 해시태그 기능 구현 (0) | 2022.12.17 |
---|---|
[React Native -16] 라디오 버튼 구현하기 (0) | 2022.12.04 |
[React Native -14] 다음 주소 검색 API 이용하기 (1) | 2022.11.25 |
[React Native -13] Web View (0) | 2022.11.24 |
[React Native -12] 사진 개수 제한 (0) | 2022.11.24 |