Khi lập trình ứng dụng mobile, có khá nhiều thứ liên quan đến hình ảnh. Hướng dẫn sau đây sẽ giúp bạn có thể upload nhiều hình ảnh trong app React Native, tương tự Facebook hay instagram…
Chuẩn bị
Trong hướng dẫn này sử dụng api code dot.net core. Bạn có thể sử dụng ngôn ngữ khác như nodejs, php, java… Bạn có thể tham khảo thêm tại đây.
Trong React Native sử dụng 3 thư viện
npm install react-native-image-crop-picker'
npm install react-native-actionsheet
npm install axios
Các bạn tham khảo thêm ở github của thư viện để biết cách cấu hình chi tiết.
Code backend API
[HttpPost]
[Route("")]
public async Task<IActionResult> Post([FromForm]List<IFormFile> files)
{
try
{
var today = DateTime.Today;
var uploadPath = @"C:\web\files\files"; // Path.Combine(_hostingEnvironment.WebRootPath, "Content", "Files");
uploadPath += $"\\{today.Year}\\{today.Month}".PadLeft(2, '0');
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
var fileUrls = new List<string>();
foreach (var file in files)
{
if (file.Length > 0)
{
var fileExtension = Path.GetExtension(file.FileName);
string fileName = $"{FileHelper.GenerateUniqueFileName}{fileExtension}";
await file.CopyToAsync(stream);
var fileUrl = $"files/{today.Year}/{today.Month}".PadLeft(2, '0') + "/" + fileName;
fileUrls.Add(fileUrl);
}
}
var fileItemResponse = new ResultDataObject
{
Data = fileUrls,
Code = (int)ErrorCodeResultEnum.Ok,
Message = "Ok"
};
return Ok(fileItemResponse);
}
catch (Exception ex)
{
var fileItemResponse = new ResultDataObject
{
Message = ex.Message,
Code = (int)ErrorCodeResultEnum.Failure
};
return Ok(fileItemResponse);
}
}
Code React Native
Chọn ảnh từ thư viện sử dụng ImagePicker, sử dụng state để lưu lại ảnh đã chọn
onActionSelectPhotoDone = index => {
switch (index) {
case 0:
ImagePicker.openCamera({}).then(image => {
this.setState({
localPhotos: [...this.state.localPhotos, image]
});
});
break;
case 1:
ImagePicker.openPicker({
multiple: true,
maxFiles: 10,
mediaType: 'photo'
}).then(images => {
images.forEach((image) => {
this.setState({
localPhotos: [...this.state.localPhotos, image]
});
});
}).catch(error => {
alert(JSON.stringify(error));
});
break;
default:
break;
}
};
Code hiển thị hình ảnh sau khi chọn
renderListPhotos = localPhotos => {
const photos = localPhotos.map((photo, index) => (
<TouchableOpacity key={index}
onPress={() => {
this.showActionSheet(index);
}}
>
<Image style={styles.photo} source={{ uri: photo.path }} />
</TouchableOpacity>
));
return photos;
};
renderSelectPhotoControl = localPhotos => {
return (
<View style={styles.sectionContainer}>
<Text style={styles.sectionTitle}>Select photos</Text>
<ScrollView style={styles.photoList} horizontal={true}>
{this.renderListPhotos(localPhotos)}
<TouchableOpacity onPress={this.onPressAddPhotoBtn.bind(this)}>
<View style={[styles.addButton, styles.photo]}>
<Text style={styles.addButtonText}>+</Text>
</View>
</TouchableOpacity>
</ScrollView>
</View>
);
};
Sử dụng axios & FormData để Upload
onDoUploadPress() {
const { localPhotos } = this.state;
if (localPhotos && localPhotos.length > 0) {
let formData = new FormData();
localPhotos.forEach((image) => {
const file = {
uri: image.path,
name: image.filename || Math.floor(Math.random() * Math.floor(999999999)) + '.jpg',
type: image.mime || 'image/jpeg'
};
formData.append('files', file);
});
axios
.post('https://api.tradingproedu.com/api/v1/fileupload', formData)
.then(response => {
this.setState({ logs: JSON.stringify(response.data) });
})
.catch(error => {
alert(JSON.stringify(error));
});
} else {
alert('No photo selected');
}
}
Chúc các bạn thành công.
Full source code https://github.com/tuanitpro/react-native-upload-files