本エントリでは作成したアプリで使用したいくつかのテクニックの一つのリストについて記載します。
カメラで撮影しコメントを付けて投稿したものを一覧で表示する機能を提供する部分です。またイイネボタンもどうしても付けたかったので実装しました。
以下ソースです。
import React, {Component} from 'react';
import {Platform, StyleSheet, TouchableOpacity, View, ListView,Image} from 'react-native';
import {
Text,
List,
ListItem,
} from "native-base";
import { NavigationActions } from "react-navigation";
import axios from 'axios';
export default class HomeScreen extends Component<Props> {
//コンストラクタ
constructor(props){
super(props); //必ず呼ぶ
this.state = {
rec:[]
}
}
getData() {
const prm ={params:{TEST:"ダミー"}};
axios
.get('https://XXXXXXX.execute-api.XXXXXXXX.amazonaws.com/dev/test',
prm,{ headers: { 'Content-Type': 'application/json' ,'Accept': 'application/json'}})
.then((results) => {
this.setState({rec:results.data.body});
console.log(JSON.stringify(results.data.body)); // <-- (5) [
}).catch(() => {
console.log('通信に失敗しました。');
});
}
async componentDidMount() {
try {
this.getData();
} catch(e) {
alert(e.message)
}
}
render() {
const rec = this.state.rec
return (
<View style={styles.container}>
<Text>リストのページです</Text>
<List dataArray={rec}
renderRow={(item) =>
<ListItem style={{flex:1,flexDirection: 'column',alignItems: 'center'}}>
<Image style={{width: 250, height: 250}} source={{uri:item.PictureFile}}/>
<Text style={{color:'#b0c4de'}}>{item.datetimestr}</Text>
<Text style={{color:'#b0c4de'}}>{item.Comment}</Text>
<TouchableOpacity onPress={() => this.handleLikeClick(item)} style={styles.capture}>
<Text style={{color:'#b0c4de'}}>{item.LikeNum}</Text>
</TouchableOpacity>
</ListItem>
} style={{backgroundColor: '#e6e6fa',bordercolor:'#4A90E2'}}> >
</List>
<TouchableOpacity onPress={() => this.props.navigation.navigate("Home")} style={styles.capture}>
<Text style={{ fontSize: 14 }}> Home</Text>
</TouchableOpacity>
</View>
)
}
handleLikeClick = (item) => {
axios
.post('https://XXXXXX.execute-api.XXXXXXX.amazonaws.com/dev/increment_like',{datetimestr:item.datetimestr},{ headers: {Accept: 'application/json','Content-Type': 'application/json'}})
.then((results) => {
console.log(JSON.stringify(results.data.body)); // <-- (5) [
}).catch(() => {
console.log('通信に失敗しました。');
});
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'aliceblue',
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20,
},
});
ここでハマったのはAWSから取得したデータはJSON形式なのですがそれをreact-Native標準のListViewで表示させようとするとうまくいかず。なので、react-baseのList,ListItemを使用しました。標準のほうは連想配列は使えず純粋な配列でないとダメなのかとか、少しこの辺は曖昧です。
あと以前の投稿にも書きましたが、リストをstateにもつ時には必ず
constructor(props){
super(props); //必ず呼ぶ
this.state = {
rec:[] //絶対いる!!
}
}
と初期化が必要です。(ホントこれには大変な思いをさせられましたw)
イイネボタンはデータの主キーに当たるdatetimestrをAWSで公開しているAPIに渡すだけのシンプルなものです。
ところで直接この話とは関係ないですがこの部分を実装している時に少し時間を喰ってしまったのはaxiosはGETの時にはパラメーターに
{params:{TEST:"ダミー"}}
とparamsを要求しますが、POSTだと
{datetimestr:item.datetimestr}
と要らないのですよね。コピペして使って少し無駄足を踏んでしまいました。
あと画像の表示はAWSのS3から直接取得しています。
そしてご覧の通りの実装なのでイイネした後数字がインクリメントされません。いろいろ方法はあるみたいですが、またエネルギーが回復したら(え゛っw)トライしてみたいと思います。
以上でリスト表示機能とイイネ機能についての篇を閉じます。