我想开发一个可以拍照并上传到AWS s3的应用程序。现在,我要在上传后从图库中删除拍摄的图像。
通过使用RNFetchBlob库,我能够实现这一目标。拍摄后,我试图删除一次图像。运行良好。但是,我想在上传到云后将其删除一次。因此,我创建了一个方法来执行此操作,并且有一个名为isUploaded的变量,该变量被设置为false,一旦上传完成,我就将该变量状态设置为true,而在render方法中,我将其称为delete images方法。但这不是删除图像。我没弄错地方。
您能帮我解决这个问题吗?
export default class Upload extends Component {
constructor(props) {
super(props);
storeFilePath :[],
saveImages :[],
isUploaded:false
}
}
takePic = async function() {
var date = new Date();
var time = date.getTime();
this.setState({capturedTime:time});
console.log(this.state.connection_Status);
if(this.state.connection_Status==="Online"){
this.getServerTime();
this.setState({capturedTime:this.state.serverTime.currentFileTime+'_'+time});
console.log(this.state.capturedTime);
console.log("availble");
}
const options = {
quality: 1.0,
maxWidth: 75,
maxHeight: 75,
base64: true
}
ImagePicker.launchCamera(options,(responce)=>{
this.state.testImage.push({ uri: responce.uri });
const file ={
uri : responce.uri,
name : responce.fileName;
method: 'POST',
width : 50,
height : 50,
path : responce.path,
type : responce.type,
notification: {
enabled: true
}
}
this.state.saveImages.push(file);
this.state.storeFilePath.push(responce.path);
})
}
_upload=(saveImages)=>{
const config ={
keyPrefix :'***/',
bucket : '****',
region :'***',
accessKey:'**************',
secretKey :'**/*+*****',
successActionStatus :201
}
this.state.saveImages.map((image) => {
RNS3.put(image,config)
.then((responce) => {
console.log('=============********************================');
console.log(image);
this.setState({ isUploaded: true });
});
});
Alert.alert('Successfully, saved');
}
deleteImages=(storeFilePath)=>{
this.state.storeFilePath.map((path) => {
RNFetchBlob.fs.unlink(path)
.then(() => {
console.log('Delete images once after file upload is done');
});
});
}
render() {
return (
if(this.state.isUploaded===true){
this.deleteImages(this.state.storeFilePath);
}
<View>
<View style={styles.Camera}>
<TouchableOpacity onPress={this.takePic.bind(this)}>
<Text>Take Picture</Text>
</TouchableOpacity>
</View>
<View style={styles.Send}>
<TouchableOpacity onPress={() => this._upload()}>
<Text>Send</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
答案 0 :(得分:0)
您正在通过takePic
函数更改状态
this.state.saveImages.push(file);
this.state.storeFilePath.push(responce.path);
这可能导致您的状态更新时突变消失。这可能意味着您上传的图像由于路径丢失而没有被删除。
您应该正确地调用setState
,方法是获取状态的先前值,添加新值,然后对其进行更新。
this.setState(prevState => {
// get the previous state values for the arrays
let saveImages = prevState.saveImages;
let storeFilePath = prevState.storeFilePath;
// add the values to the arrays like before
saveImage.push(file);
storeFilePath.push(responce.path);
// return the new state
return {
saveImages,
storeFilePath
}
});
如果您想检查状态是否刚刚设置,则应该不执行以下操作:
this.setState({capturedTime:this.state.serverTime.currentFileTime+'_'+time});
console.log(this.state.capturedTime); // <- this is not guaranteed to be correct
您应使用 setState
随附的回调函数。您应该将代码更新为:
this.setState({capturedTime:this.state.serverTime.currentFileTime+'_'+time},
() => console.log(this.state.capturedTime)
);
这将确保state
已被更新,以便您的console.log应该为您显示正确的值。
在deleteImages
函数中,您正在传递参数storeFilePath
,但由于直接从storeFilePath
访问state
而不使用它。
deleteImages=(storeFilePath)=>{ // <- storeFilePath is not used
this.state.storeFilePath.map((path) => {
RNFetchBlob.fs.unlink(path)
.then(() => {
console.log('Delete images once after file upload is done');
});
});
}
您可以使用它并将函数重写为:
deleteImages=(storeFilePath)=>{
storeFilePath.map((path) => {
RNFetchBlob.fs.unlink(path)
.then(() => {
console.log('Delete images once after file upload is done');
});
});
}
或者您可以一起忽略该参数并执行以下操作:
deleteImages=()=>{
this.state.storeFilePath.map((path) => {
RNFetchBlob.fs.unlink(path)
.then(() => {
console.log('Delete images once after file upload is done');
});
});
}
您不应该在deleteImages
中调用render
函数。您应该使用React组件的生命周期方法。
我们可以使用componentDidUpdate
检查图像是否已上传,然后致电
deleteImages
componentDidUpdate(prevProps, prevState) {
if (this.state.isUploaded) {
this.deleteImages(); // <- see above about refactoring this function
}
}
我不是100%确信这是上传的正确方法。就像在deleteImages
中一样,您没有使用要传递的参数。
_upload=(saveImages)=>{
const config ={ ... }
this.state.saveImages.map((image) => {
RNS3.put(image,config)
.then((responce) => {
console.log('=============********************================');
console.log(image);
this.setState({ isUploaded: true });
});
});
Alert.alert('Successfully, saved');
}
我认为您可能应该使用Promise.all
(似乎更多here)来处理这些问题。此外,您上传的每个图像都会调用this.setState({ isUploaded: true });
,触发重新渲染并调用deleteImages
函数,因为状态现在为true。这样的事情可能会更好:
_upload () => { // <- again you are not using the parameter that you are passing
const config = { ... }
Promise.all(this.state.saveImages.map(image => RNS3.put(image, config))).then(values => {
this.setState({isUploaded: true});
alert('Successfully, saved);
// though why delete images on a state change, why not delete them here now that the upload has completed?
})
}
以下是setState
上的一些很棒的文章。