使用一个小的照片上传应用程序,我正在React Native上构建。我有一个呈现所有上传内容(通过SQLite)的屏幕和一个可以调用进行上传的模式。
因此,当我点击“提交”时,就会发生上传,并且模式会按预期消失。但是,由于屏幕及其组件未重新加载,因此不会调用ComponentDidLoad。这意味着除非重新加载应用程序(它是单页应用程序),否则我的新上传内容不会出现在屏幕上。我也有一个更新功能,但是我不确定如何调用它。
所以我的问题是,当通过模态上的其他组件进行上传时,应该如何在屏幕上调用更新?
Myform.js (负责上载的组件):
class Myform extends React.Component {
state = {
imageData: null,
caption: null,
base64URI: null
}
//choose the photo. Should be in base64.
getPhotoFromGallery = () => {
ImagePicker.launchImageLibrary({}, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else {
// this.add(response.uri)
this.setState({ imageData: response });
this.setState({ base64URI: response.uri });
}
});
};
//show image in component
showPickedImage() {
const { imageData } = this.state;
if (imageData !== null) {
return (
<Image
source={{ uri: imageData.uri }}
style={{ alignSelf: 'center', width: Dimensions.get('window').width, height: Dimensions.get('window').width }}
/>
);
} else {
return (
<View>
<TouchableOpacity
style={styles.addPhoto}
onPress={this.getPhotoFromGallery}
>
<Icon name="image" size={164} color="#F1F1F2" />
</TouchableOpacity>
</View>
);
}
}
//submit image to SQLite. Should insert into table and reset the image picker
onSubmit = () => {
const { base64URI } = this.state;
if (base64URI != null) {
//add into SQlite
this.add(base64URI);
this.setState({ caption: null, imageData: null, base64URI: null });
console.log('text')
console.log('submitted')
// this.props.navigate.navigation('Vault'),
Alert.alert(
'Success',
'Uploaded!',
[
{
text: 'Ok!',
},
],
);
}
}
//create table if not existing. Where should componentDidMount be placed?
componentDidMount() {
db.transaction(tx => {
tx.executeSql(
'create table if not exists items (id integer primary key not null, value text);'
);
});
}
render() {
const { image } = this.props;
return (
<View style={styles.container}>
<View style={styles.container}>
{this.showPickedImage()}
<TouchableHighlight style={styles.submit} onPress={this.onSubmit}>
<Text>Submit</Text>
</TouchableHighlight>
</View>
</View>
);
}
add(text) {
db.transaction(
tx => {
tx.executeSql('INSERT INTO items (value) values (?)', [text]);
},
null,
this.update
);
}
update = () => {
this.todo && this.todo.update();
this.done && this.done.update();
};
}
VaultScreen.js (负责显示上传内容的组件):
import React from 'react';
import { View, TextInput, SafeAreaView, Button, Text, Alert, Image, TouchableOpacity, StyleSheet, ScrollView, Platform, TouchableWithoutFeedback, StatusBar, TouchableHighlight, Dimensions, FlatList } from 'react-native';
import { openDatabase } from 'react-native-sqlite-storage';
var db = openDatabase({ name: 'UserDatabase.db' });
import styles from './Styles'
import VaultHeader from './components/VaultHeader'
import AddButton from './components/AddPhotoButton'
import Myform from './components/Myform';
export default class VaultScreen extends React.Component {
state = {
items: [],
itemsFormatted: [],
photo_id: null,
value: ''
};
formatItems = () => {
const { items } = this.state
const newItems = []
const numberOfFullRows = Math.floor(items.length / 3);
let numberOfElementsLastRow = 1
// items.length - (numberOfFullRows * 3);
while (numberOfElementsLastRow !== 3 && numberOfElementsLastRow !== 0) {
newItems.push({ key: `blank-${numberOfElementsLastRow}`, empty: true });
numberOfElementsLastRow++;
}
return this.setState({ itemsFormatted: newItems })
};
renderItem = ({ item }) => {
const { items } = this.state;
if (item.empty === true) {
return <View style={[styles.item, styles.itemInvisible]} />;
}
return (
<TouchableOpacity style={styles.item} onPress={this.deletePhoto} key={item.id}>
<Image source={{ uri: item.value }} style={{ flex: 1, width: '100%', height: undefined }} />
</TouchableOpacity>
);
};
selectPhoto = () => {
const { photo_id } = this.state;
console.log(this.photo_id);
db.transaction(tx => {
tx.executeSql(
'SELECT * FROM items where id = ?',
[photo_id],
(tx, results) => {
var len = results.rows.length;
console.log('len', len);
if (len > 0) {
this.setState({
value: results.rows.item(0),
});
} else {
Alert.alert(
'Failed',
'Not Found',
[
{
text: 'Try Again',
},
],
{ cancelable: false }
);
this.setState({
value: '',
});
}
}
);
});
};
deletePhoto = () => {
this.selectPhoto()
const { photo_id } = this.state;
console.log('delete attempt')
console.log(photo_id)
db.transaction(tx => {
tx.executeSql('DELETE FROM items where id=?', [photo_id],
(tx, results) => {
console.log('Results', results.rowsAffected);
if (results.rowsAffected > 0) {
Alert.alert(
'Success',
'Photo deleted successfully',
[
{
text: 'Ok',
},
],
{ cancelable: false }
);
} else {
return null;
}
}
);
});
};
async componentDidMount() {
this.formatItems()
db.transaction(tx => {
tx.executeSql(`SELECT * FROM items;`, [], (tx, results) => {
var temp = [];
for (let i = 0; i < results.rows.length; ++i) {
temp.push(results.rows.item(i));
}
temp.reverse()
this.setState({
items: temp,
});
this.setState({
itemsFormatted: this.state.items.concat(this.state.itemsFormatted)
})
console.log(this.state.items.id.count)
});
})
}
render() {
return (
<SafeAreaView style={{flex:1, backgroundColor: 'white'}}>
<VaultHeader/>
<TextInput
placeholder="Search Vault"
placeholderTextColor='#999999'
style={{
backgroundColor: '#F1F1F2',
height: 40,
fontSize: 16,
paddingLeft: 17,
color: 'black',
borderRadius: 10,
width: '92%',
alignSelf: 'center',
marginBottom: 10
}}
// onChangeText={value => this.searchContacts(value)}
/>
<FlatList
data={this.state.items, this.state.itemsFormatted}
style={styles.grid}
renderItem={this.renderItem}
keyExtractor={item => item.id}
numColumns= {3}
/>
<View style={{alignItems: 'center', bottom: 0}}>
<View style={{backgroundColor: 'white', width: '100%', height: 55, alignItems: 'center', justifyContent: 'center'}}>
<AddButton />
</View>
</View>
</SafeAreaView>
);
}
//update function to load items from DB
update() {
db.transaction(tx => {
tx.executeSql(
`select * from items`,
(_, { rows: { _array } }) => this.setState({ items: _array })
);
});
}
}