React Native 使用react-native-image-picker库实现图片上传功能

前端之家收集整理的这篇文章主要介绍了React Native 使用react-native-image-picker库实现图片上传功能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱。

react-native-image-picker使用

1, 首先,安装下该插件

  1. npm install react-native-image-picker@latest --save

2, 针对Android和iOS平台分别进行配置

## android 平台配置

1,在android/settings.gradle文件添加如下代码

  1. include ':react-native-image-picker'
  2. project(':react-native-image-picker').projectDir = new File(settingsDir,'../node_modules/react-native-image-picker/android')

2,在android/app/build.gradle文件的dependencies中添加如下代码

  1. compile project(':react-native-image-picker')

3,在AndroidManifest.xml文件添加权限:

  1. <uses-permission android:name="android.permission.CAMERA" />
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

4,最后在MainApplication.Java文件添加如下代码

  1. import com.imagepicker.ImagePickerPackage;
  2. new ImagePickerPackage()

这样Android环境就配置好了。

iOS平台配置

1,打开Xcode打开项目,点击根目录,右键选择 Add Files to ‘XXX’,选中项目中的该路径下的文件即可:node_modules -> react-native-image-picker -> ios -> select RNImagePicker.xcodeproj

2,添加成功后使用link命令:react-native link react-native-image-picker 。
3,打开项目依次使用Build Phases -> Link Binary With Libraries将RNImagePicker.a添加到项目依赖。

4,对于iOS 10+设备,需要在info.plist中配置NSPhotoLibraryUsageDescription和NSCameraUsageDescription。

react-native-image-picker示例

为了项目使用的方便,我们将其封装为一个组件CameraButton.js。代码如下:

  1. import React from 'react'
  2. import {
  3. TouchableOpacity,StyleSheet,Platform,ActivityIndicator,View,Text,ToastAndroid
  4. } from 'react-native'
  5.  
  6. var ImagePicker = require('react-native-image-picker');
  7. import Icon from 'react-native-vector-icons/Ionicons';
  8.  
  9. const options = {
  10. title: '选择图片',cancelButtonTitle: '取消',takePhotoButtonTitle: '拍照',chooseFromLibraryButtonTitle: '图片库',cameraType: 'back',mediaType: 'photo',videoQuality: 'high',durationLimit: 10,maxWidth: 600,maxHeight: 600,aspectX: 2,aspectY: 1,quality: 0.8,angle: 0,allowsEditing: false,noData: false,storageOptions: {
  11. skipBackup: true,path: 'images'
  12. }
  13. };
  14.  
  15. class CameraButton extends React.Component {
  16. constructor(props){
  17. super(props);
  18. this.state = {
  19. loading:false
  20. }
  21. }
  22. render() {
  23. const {photos,type} = this.props;
  24. let conText;
  25. if(photos.length > 0){
  26. conText = (<View style={styles.countBox}>
  27. <Text style={styles.count}>{photos.length}</Text>
  28. </View>);
  29. }
  30. return (
  31. <TouchableOpacity
  32. onPress={this.showImagePicker.bind(this)}
  33. style={[this.props.style,styles.cameraBtn]}>
  34. <View>
  35. <Icon name="md-camera" color="#aaa" size={34}/>
  36. {conText}
  37. </View>
  38. </TouchableOpacity>
  39. )
  40. }
  41.  
  42. showImagePicker() {
  43. ImagePicker.showImagePicker(options,(response) => { if (response.didCancel) { console.log('User cancelled image picker'); } else if (response.error) { console.log('ImagePicker Error: ',response.error); } else { let source; if (Platform.OS === 'android') { source = {uri: response.uri,isStatic: true} } else { source = {uri: response.uri.replace('file://',''),isStatic: true} } let file; if(Platform.OS === 'android'){ file = response.uri }else { file = response.uri.replace('file://','') } this.setState({ loading:true }); this.props.onFileUpload(file,response.fileName||'未命名文件.jpg') .then(result=>{ this.setState({ loading:false }) }) } }); } } const styles = StyleSheet.create({ cameraBtn: { padding:5 },count:{ color:'#fff',fontSize:12 },fullBtn:{ justifyContent:'center',alignItems:'center',backgroundColor:'#fff' },countBox:{ position:'absolute',right:-5,top:-5,backgroundColor:'#34A853',width:16,height:16,borderRadius:8,justifyContent:'center' } }); export default CameraButton;

然后在需要使用的地方引入。

  1. import CameraButton from '../../component/huar/cameraButton'
  2.  
  3.  
  4. <CameraButton style={styles.cameraBtn}
  5. photos={[]}
  6. onFileUpload={this.onFileUpload} />
  7. 点击上传事件:
  8. onFileUpload(file,fileName){
  9. return this.props.uploadAvatar({
  10. id: this.props.user.ID,type:'logo',obj:'user',corpId: this.props.cropId
  11. },file,fileName)}
  12. Action请求代码
  13. function actions(dispatch) {
  14. return {
  15. fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params,fileUrl,fileName))
  16. }
  17. }

actions中的uploadAvatar函数如下。

  1. function uploadAvatar(params,fileUrl,fileName) {
  2. return dispatch=> {
  3. return UserService.uploadImage(params,fileName)
  4. .then(result=> {
  5. dispatch({
  6. type: UPDATE_AVATAR,path: result.path
  7. })
  8. return result
  9. })
  10. }
  11. }
  12. //UserService.uploadImage代码如下
  13. export function uploadImage(params,fileName) {
  14. return http.uploadFile(`${config.UploadImage}`,params,fileName)
  15. }

UserService函数的http异步上传图片代码如下:

  1. let queryString = require('query-string');
  2. import Storage from './storage'
  3. import {
  4. Platform
  5. } from 'react-native'
  6.  
  7. const os = Platform.OS;
  8.  
  9. async function uploadFile(url,params,fileName) {
  10. let Access_Token = await Storage.getItem('Access_Token');
  11. let data = new FormData();
  12.  
  13. data.append('file',{
  14. uri: fileUrl,name: fileName,type: 'image/jpeg'
  15. });
  16.  
  17. Object.keys(params).forEach((key)=> { if (params[key] instanceof Date) { data.append(key,value.toISOString()) } else { data.append(key,String(params[key])) } }); const fetchOptions = { method: 'POST',headers: { 'Accept': 'application/json','Access_Token': Access_Token ? Access_Token : '','UserAgent':os },body: data }; return fetch(url,fetchOptions) .then(checkStatus) .then(parseJSON) }

封装上传

如果上面的实现看的比较复杂,那么我们做如下的封装:

  1. let common_url = 'http://192.168.1.1:8080/'; //服务器地址
  2. let token = ''; //用户登陆后返回的token
  3.  
  4. function uploadImage(url,params){
  5. return new Promise(function (resolve,reject) {
  6. let formData = new FormData();
  7. for (var key in params){
  8. formData.append(key,params[key]);
  9. }
  10. let file = {uri: params.path,type: 'application/octet-stream',name: 'image.jpg'};
  11. formData.append("file",file);
  12. fetch(common_url + url,{
  13. method: 'POST',headers: {
  14. 'Content-Type': 'multipart/form-data;charset=utf-8',"x-access-token": token,},body: formData,}).then((response) => response.json()) .then((responseData)=> { console.log('uploadImage',responseData); resolve(responseData); }) .catch((err)=> { console.log('err',err); reject(err); }); }); }

然后在使用的地方:

  1. let params = {
  2. userId:'abc12345',//用户id
  3. path:'file:///storage/emulated/0/Pictures/image.jpg' //本地文件地址
  4. }
  5. uploadImage('app/uploadFile',params )
  6. .then( res=>{
  7. //请求成功
  8. if(res.header.statusCode == 'success'){
  9. //这里设定服务器返回的header中statusCode为success时数据返回成功
  10. upLoadImgUrl = res.body.imgurl; //服务器返回的地址
  11. }else{
  12. //服务器返回异常,设定服务器返回的异常信息保存在 header.msgArray[0].desc
  13. console.log(res.header.msgArray[0].desc); } }).catch( err=>{ //请求失败 })

附:http://lib.csdn.net/article/reactnative/58022?knId=1415
使用fetch+formData实现图片上传

猜你在找的React相关文章