I have attempted to implement the item picker which powered by NativeBase UI framework but I have no idea why it keeps throwing this error when I tap my item picker on the app itself. I have checked the available discussion in Stackoverflow but none of them be replied an appropriate for this issue. Meanwhile, in my code does not have VirtualizedLists at all. On the other hand, I also attach the code as below too.
I really hope someone can help me on this. Thanks.
import React, { Component } from "react";
import {
StyleSheet,
TouchableOpacity,
RefreshControl,
ScrollView,
SafeAreaView
} from 'react-native';
import CustomHeader from './CustomHeader';
import { Content, Button, H3, Text, Grid, Row, Card, Col, CardItem, Body, Toast, Container, Root, Icon, Item, Picker, Spinner } from 'native-base';
import axios from "axios";
import { ApiURL } from "../util/constant";
import Moment from 'moment';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { backToLogin } from "../util/auth";
class TransactionScreen extends Component {
constructor(props) {
super(props);
this.state = {
accessToken: null,
transactions: [],
selected2: undefined,
page: 0,
isLoading: true,
boolLoadMoreBtn: false,
viewType: ['Payment', 'Refund', 'Topup']
}
}
async getAccessToken() {
token = await AsyncStorage.getItem('@access_token');
this.setState({ accessToken: token });
}
onValueChange2(value) {
this.setState({ selected2: value, page: 0, isLoading: true });
this.loadTransactionData(value, true);
}
loadTransactionData(whereBy = null, newView = false) {
if (this.state.accessToken.length === 0){
return;
}
const objPayload = {};
if (whereBy != null) {
objPayload.whereBy = whereBy;
}
var page = this.state.page;
if (newView === true) {
page = 0;
}
const newPage = parseInt(page) + 1;
this.setState({ page: newPage });
axios.post(
`${ApiURL}/wallet/transaction?page=${newPage}`,
objPayload,
{
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${this.state.accessToken}`
}
}
).then(resp => {
this.setState({isLoading: false});
if (resp.status === 200) {
const res = resp.data.transaction;
if (newPage === 1) {
console.log(res);
this.setState({ transactions: res, boolLoadMoreBtn: true, isLoading: false });
}
else {
const r = this.state.transactions;
res.map(i => {
r.push(i);
})
this.setState({ transactions: r, boolLoadMoreBtn: true });
}
}
else {
Toast.show({
text: resp.data.error,
buttonText: 'OK'
});
return;
}
}).catch((error) => {
this.setState({isLoading: false});
if (error.response) {
if (error.response.status === 401) {
backToLogin(this.props);
}
else if (error.response.status === 404){
if (newPage === 1){
this.setState({transactions:[]});
}
}
else {
this.setState({ boolLoadMoreBtn: false });
}
} else {
Toast.show({
text: error.message,
buttonText: 'OK'
});
return;
}
});
}
openDetail(transactionId) {
this.props.navigation.navigate('TransactionDetail', { transactionId: transactionId, backScene: 'Transaction' });
}
componentDidMount() {
this._navListener = this.props.navigation.addListener("didFocus", () => {
this.getAccessToken().then(() => {
this.loadTransactionData();
});
});
}
static navigationOptions = () => ({
headerShown: false
})
pullMoreData() {
const newPage = parseInt(this.state.page) + 1;
this.setState({ page: newPage });
this.loadTransactionData();
}
render() {
return (
<Root>
<Container>
<CustomHeader isHome={false} navigation={this.props.navigation} backScene="Home" title="Transaction" />
<Content refreshControl={
<RefreshControl
//refresh control used for the Pull to Refresh
refreshing={this.state.isLoading}
onRefresh={() => this.loadTransactionData(this.state.selected2 === undefined ? null : this.state.selected2, true)}
/>
}>
<Item picker>
<Picker
mode="dropdown"
iosIcon={<Icon name="arrow-down" />}
style={{ width: undefined }}
placeholder="All"
Header="Transaction Type"
iosHeader="Transaction Type"
placeholderStyle={{ color: "#bfc6ea" }}
placeholderIconColor="#007aff"
selectedValue={this.state.selected2}
onValueChange={this.onValueChange2.bind(this)}
>
<Picker.Item label="Payment" value="Payment" />
<Picker.Item label="Top up" value="Topup" />
<Picker.Item label="Refunded" value="Refunded" />
</Picker>
</Item>
{
this.state.isLoading === true ? <Spinner /> :
Object.keys(this.state.transactions).length > 0 ?
this.state.transactions.map((transaction, i) => {
const dt = Moment(transaction.createdAt).format('L LTS');
return (
<TouchableOpacity key={transaction.id} onPress={() => this.openDetail(transaction.id)}>
<Card key={i}>
<CardItem key={transaction.id + "1"} style={{ borderBottomWidth: 1, borderColor: "#f8f9fa", backgroundColor: "#f8f9fa" }} header>
<Grid>
<Row>
<Col size={55}><Text style={{ alignSelf: "flex-start" }}>{dt}</Text></Col>
<Col size={45}><Text style={{ alignSelf: "flex-end" }}>{transaction.mode}</Text></Col>
</Row>
</Grid>
</CardItem>
<CardItem key={transaction.id + "2"}>
<Grid>
<Row style={{ marginBottom: 5 }}>
<Col><H3>{transaction.merchant}</H3></Col>
</Row>
<Row style={{ marginBottom: 5 }}>
<Col><Text style={{ alignSelf: "flex-start" }}>RM {parseFloat(transaction.amount).toFixed(2)}</Text></Col>
</Row>
<Row>
<Col><Text style={{ fontSize: 12 }}>S/N:{transaction.id}</Text></Col>
</Row>
</Grid>
</CardItem>
</Card>
</TouchableOpacity>
)
}) : <Card key={9999}>
<CardItem>
<Body><Text>No Transaction is available now</Text></Body>
</CardItem>
</Card>
}
{
this.state.boolLoadMoreBtn === true && (
<Button onPress={() => this.loadTransactionData(this.state.selected2 === undefined ? null : this.state.selected2)} style={{ backgroundColor: "#f8f9fa" }} disabled={(this.boolLoadMoreBtn === true ? true : false)} light block><Text>Load More</Text></Button>
)
}
</Content>
</Container>
</Root>
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1
}
});
export default TransactionScreen;
