Javascript TypeError:undefined不是对象(正在计算';this.state.imagesID';)

Javascript TypeError:undefined不是对象(正在计算';this.state.imagesID';),javascript,react-native,react-redux,aws-sdk,Javascript,React Native,React Redux,Aws Sdk,当我试图上传图片时,我遇到了一个奇怪的错误。上传到服务器可以正常工作,但在我发现错误后立即上传。当我只上传文本时,它可以正常工作,但当我在上传后尝试使用imagesID时,它会出现此错误。有人知道我为什么会出现这个错误,以及如何修复它吗 我在upload()函数内的xhr.onreadystatechange中的“this.state.imagesID.push({key:key});”行上得到错误 我在类中输入了以下错误: 'use strict'; import React, { Comp

当我试图上传图片时,我遇到了一个奇怪的错误。上传到服务器可以正常工作,但在我发现错误后立即上传。当我只上传文本时,它可以正常工作,但当我在上传后尝试使用imagesID时,它会出现此错误。有人知道我为什么会出现这个错误,以及如何修复它吗

我在upload()函数内的xhr.onreadystatechange中的“this.state.imagesID.push({key:key});”行上得到错误

我在类中输入了以下错误:

'use strict';

import React, { Component } from 'react';
import {
  Image,
  Text,
  TextInput,
  Keyboard,
  TouchableOpacity,
  TouchableHighlight,
  TouchableNativeFeedback,
  View,
  ScrollView,
  Modal,
  Navigator,
  StyleSheet,
  Dimensions,
  NativeModules
} from 'react-native';
import { connect } from 'react-redux';
import {newFeed} from './api/FeedAPI';
import {showNewFeedPage} from './actions/NewFeedAction';
//import {Auth,ImgOps,Conf,Rs,Rpc} from 'react-native-qiniu';
import ImagePicker from 'react-native-image-crop-picker';
import Md5 from './util/Md5';
import KeyboardSpacer from 'react-native-keyboard-spacer';
import URLConf from './api/URLConf';
import {getToken} from './util/Secret';
import Secret from './util/Secret';


const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const margin = 20;
const imgInterval = 5;
const imgCountLimit = 9;
const textLengthLimit = 140;

const PRE_URL = URLConf.API_HOST + '/psu/';
const PUT_PRE_URL = PRE_URL + 'put';
const GET_PRE_URL = PRE_URL + 'get';

class NewFeed extends Component {

  constructor(props) {
    super(props);

    this.state = {
      text: '',
      images: [],
      imagesID: [], //上传图片返回的 hash id
      tags: [], //已经添加的tag
      tag: '',  //正在输入的tag
      tagCountLimit: 5,
      uploadAlready: false,
      animated: true,
      modalVisible: true,
      transparent: false,
    };
  }

  cancle() {
    this.props.showNewFeedPage(false);
    this.props.callback();
  }

  pickMultiple() {
    ImagePicker.openPicker({
      multiple: true,
      maxFiles: imgCountLimit - this.state.images.length,
    }).then(images => {
      var newImages = this.state.images;
      images.map((i, index) => {
        console.log('received image', i);
        newImages.push({uri: i.path, width: i.width, height: i.height, mime: i.mime, index: index});
      });
      this.setState({
        images: newImages,
      });
    }).catch(e => {});

  }

  genId(){//Microscopic chance that the ID generated is one that already exists, but can plan for that later
   return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
       var r = Math.random() * 16 | 0,
         v = c == 'x' ? r : (r & 0x3 | 0x8);
       return v.toString(16);
     }).toUpperCase();
  }

  upload() {//NEW UPLOAD!

    if(this.state.images !== null && this.state.images.length != 0) {
      //let formData = new FormData();

      for(let img of this.state.images) {
        let key = this.genId()+'.'+img.mime.replace('image/','');
        console.log('img upload key:'+key);
        console.log('img.mime: ' + img.mime);
        let formData = {
          key: key,
        };
        //var psu = "";
        //First get a presigned URL from the server
        //console.log('call back fun: ' +callback);
        console.log('getting a presigned url')
        getToken((token) => {
          var path = PUT_PRE_URL+ "/"+ key;
          var sign = Md5.hex_md5(path.replace(URLConf.APP_SERVER_HOST, '') + '?ts=123456&'+Secret.secret);
          console.log('sign:' + sign);
          var url = path+'?ts=123456&sign=' + sign;
          console.log("url: " + url);
          var options = {
            //method: 'POST',
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json',
              'X-Auth-Token':token,
            }//,
            //body: encodeURI(JSON.stringify({objectKey: key}), 'utf-8')

          };
          console.log('[GET] ' + url);
          fetch(url, options)
            .then((response) => response.json())
            .then((responseData) => {
              console.log('[RTN] '+responseData);
              console.log('[RTN] json stringified: ' + JSON.stringify(responseData));
              var psu=responseData.data.url;
              console.log('PSU: ' + psu);

              if(psu !== null){
                    //then once you have presigned url, upload the image
                    const xhr = new XMLHttpRequest();
                    xhr.open('PUT', psu);
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState === 4) {
                            if (xhr.status === 200) {
                              console.log('Image successfully uploaded to S3');
                              console.log(key+' upload success');
                              this.state.imagesID.push({key:key });
                              if(this.state.imagesID.length == this.state.images.length) {
                                newFeed(this.state.text, this.state.imagesID, this.state.tags, (result, id) => {
                                  if(result) {
                                    this.clearState();
                                  }
                                });
                            }
                            } else {
                              console.log('Error while sending the image to S3');
                              console.log('XHR ResponseText: ' + xhr.responseText);
                            }
                        }
                    }
                    console.log("image uri: " + img.uri);
                    xhr.setRequestHeader('Content-Type', img.mime);//'image/jpeg'
                    xhr.send({ uri: img.uri, type: img.mime, name: key});//name: 'myimage.jpg'})


              }
            })
            .done();
        });

        // Rpc.uploadFile(img.uri, uptoken, formData).then(
        //   (responseData) => {
        //     if(responseData.status == 200) {
        //       console.log(key+' upload success');
        //       this.state.imagesID.push({key:key });
        //       if(this.state.imagesID.length == this.state.images.length) {
        //          newFeed(this.state.text, this.state.imagesID, this.state.tags, (result, id) => {
        //            if(result) {
        //              this.clearState();
        //            }
        //          });
        //       }
        //     }
        //   }
        // );
      }
      this.cancle();
    } else {
      newFeed(this.state.text, '', this.state.tags, (result, id) => {
        if(result) {
          this.clearState();
        }
      });
      this.cancle();
    }
  }


  clearState() {
    this.setState({
      text: '',
      images: [],
      imagesID: [], //上传图片返回的 hash id
      tags: [], //已经添加的tag
      tag: '',  //正在输入的tag
      uploadAlready: false,
    });
  }



  delImg(index) {
    this.state.images.splice(index, 1);
  }

  renderImgsPicked() {
    var imgViews = [];
    if(this.state.images !== null && this.state.images.length != 0) {
      for(let img of this.state.images) {
        imgViews.push(<View style={styles.imgWrapper}>
                        {/* <Text style={styles.delIcon} onPress={this.delImg(img.index)}>x</Text> */}
                        <Image style={styles.img} source={img} />
                      </View>
                    );
      }
    }

    if(this.state.images.length < imgCountLimit) {
      imgViews.push(<View style={styles.imgWrapper}>
                      {/* <Text style={styles.delIcon} onPress={this.delImg(img.index)}>x</Text> */}
                      <TouchableOpacity onPress={()=>this.pickMultiple()}>
                        <Image style={styles.img} source={require('./imgs/pickBtn.png')} />
                      </TouchableOpacity>
                    </View>);
    }
    //this.upload();

    return imgViews || <View/>;
  }

  send() {
    this.upload();
  }

  checkTagInput(tag) {
    //empty check
    if(tag.indexOf(' ') == 0) return;

    //end input with blank space
    //TODO: ALSO ALLOW END INPUT WITH PRESSING ENTER(RETURN)
    if(tag.indexOf(' ') > 0) {
      tag = tag.replace(/(^\s*)|(\s*$)/g,"");
      console.log('['+tag+']');
      for(let i in this.state.tags) {
        if(this.state.tags[i] == tag) {
          return;
        }
      }
      this.state.tags.push(tag);
      this.setState({tag: ''});
    } else {
      this.setState({tag: tag});
    }

    //console.log('['+tag+']');
  }

  delTag(tag) {
    console.log('del ' + tag);
    var tags = this.state.tags;
    for(let i in tags) {
      if(tags[i] == tag) {
        tags.splice(i,1);
        break;
      }
    }
    this.setState({tags: tags});
  }

  renderTags() {
    var tagViews = [];
    for(let i in this.state.tags) {
      tagViews.push(<TouchableOpacity style={styles.tag} onPress={() => this.delTag(this.state.tags[i])}>
                      <Text style={{color: '#9B9B9B'}}>{this.state.tags[i]} X</Text>
                    </TouchableOpacity>);
    }
    return tagViews;
  }

  render() {
    const {newFeedPageVisible} = this.props;
    var modalBackgroundStyle = {
      backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
    };
    var innerContainerTransparentStyle = this.state.transparent
      ? {backgroundColor: '#fff', padding: 20}
      : null;
    return (
      //<View style={styles.container}>
        <Modal
          animationType={"slide"}
          transparent={this.state.transparent}
          visible={newFeedPageVisible}>
            <View style={styles.nav}>
              <View style={styles.cancleBtn}>
                <Text onPress={()=>this.cancle()}>cancel</Text>
              </View>
              <View style={styles.title}><Text style={{textAlign: 'center', fontWeight: 'bold'}}>Create a post</Text></View>
              <View style={styles.sendBtn}>
                <TouchableOpacity onPress={()=>this.send()}>
                  <Text style={{textAlign: 'right', color: '#00B5AD'}}>Send</Text>
                </TouchableOpacity>
              </View>
            </View>
            <ScrollView style={{ flex: 1, flexDirection: 'column'}}>

              <View style={styles.input}>
                <View>
                  <TextInput
                    style={styles.multiline}
                    placeholder="Say something..."
                    returnKeyType="next"
                    autoFocus={true}
                    multiline={true}
                    keyboardType='twitter'
                    maxLength = {140}
                    value={this.state.text}
                    onChangeText={(text) => this.setState({text})}
                  />
                  <Text style={{position: 'absolute', bottom: 10, right: 20, color: '#9B9B9B'}}>{textLengthLimit-this.state.text.length}</Text>
                </View>

              </View>
              <View style={styles.imgContainer}>
                  {this.renderImgsPicked()}
              </View>
              <View style={styles.tagsContainer}>
                <View style={{flex:1, flexDirection: 'row'}}>
                  {/* <Image style={styles.tagIcon} source={require('./imgs/tag.png')} /> */}
                  <Text style={styles.tagIcon}>#</Text>
                  <TextInput
                    style={styles.tagInput}
                    placeholder="add tag"
                    returnKeyType="done"
                    autoFocus={false}
                    multiline={false}
                    keyboardType='twitter'
                    maxLength = {140}
                    value={this.state.tag}
                    onChangeText={(tag) => {this.checkTagInput(tag)}}
                  />
                  </View>
                <View style={styles.tags}>
                {this.state.tags.length > 0 &&  this.renderTags()}
                </View>
              </View>
              <KeyboardSpacer/>
            </ScrollView>

        </Modal>

      //</View>
    );
  }
};


var styles = StyleSheet.create({
  container: {
    //justifyContent: 'center',
    //marginTop: 70,
    //padding: 20,
    flex : 1,
    // backgroundColor: '#ffffff',
  },
  innerContainer: {
    borderRadius: 10,
    alignItems: 'center',
  },
  title: {
    flex: 1,
  },
  cancleBtn: {
    width: 50,
  },
  sendBtn: {
    width: 50,
  },
  wrap: {
    flex: 1,
    flexDirection:'column',
  },
  nav: {
    //flex: 1,
    flexDirection: 'row',
    height: 70,
    paddingTop: 35,
    paddingLeft: 10,
    paddingRight: 10,
    borderBottomWidth: 0.3,
    borderBottomColor: '#9B9B9B',
  },
  input: {
    //flex:1,
    //position: 'relative',
    //flexDirection:'column',
  },
  footer: {
    height: 30,
    backgroundColor:'#ff99ff',
  },
  multiline: {
    // borderWidth: 1,
    // borderColor: 'black',
    flex: 1,
    fontSize: 18,
    height: 150,
    padding: 20,
    paddingBottom: 40,
  },
  tagIcon: {
    width: 20,
    height: 40,
    color: '#9B9B9B',
    fontSize: 23,
    marginLeft: 20,
  },

  tagsContainer: {
    flex:1,
    height: 100,
    marginBottom: 50,
  },
  tagInput: {
    flex:1,
    height: 30,
    // borderWidth: 1,
    // borderColor: 'black',
    width: windowWidth-margin*4,
    marginRight: 20,
    //marginLeft: margin,
  },
  tags: {
    flex: 1,
    flexDirection: 'row',
    flexWrap: 'wrap',
    width: windowWidth-margin*2,
    height: 100,
    margin: margin,
    marginTop: 30,
    // borderWidth: 1,
    // borderColor: 'black',
  },
  tag: {
    height: 26,
    marginRight: 10,
    marginBottom: 5,
    padding: 5,
    paddingLeft: 10,
    paddingRight: 10,
    backgroundColor: '#F3F3F3',
    // borderColor: '#adadad',
    // borderWidth: 0.5,
    borderRadius: 5,
  },
  imgContainer: {
    //height: windowHeight - 70 - 150 - 30,
    flexDirection: 'row',
    flexWrap: 'wrap',
    paddingTop: 0,
    marginLeft: margin,
    marginBottom: 20,
  },
  imgWrapper: {
    position: 'relative',
    width: (windowWidth-margin*2-imgInterval*2) / 3,
    height:(windowWidth-margin*2-imgInterval*2) / 3,
    marginBottom: imgInterval,
    marginRight: imgInterval,
  },
  img: {
    width: (windowWidth-margin*2-imgInterval*2) / 3,
    height:(windowWidth-margin*2-imgInterval*2) / 3,
    marginBottom: imgInterval,
    marginRight: imgInterval,
    resizeMode: 'cover',
  },
  delIcon: {
    position: 'absolute',
    top:0,
    right: 0,
    zIndex: 1,
    backgroundColor: 'rgba(0,0,0,0)',
  }

});


export default connect((state) => ({
  newFeedPageVisible: state.showNewFeedPage.newFeedPageVisible,
}), (dispatch) => ({
  showNewFeedPage: (flag) => dispatch(showNewFeedPage(flag)),
}))(NewFeed)
“严格使用”;
从“React”导入React,{Component};
进口{
形象,,
文本,
文本输入,
键盘
可触摸不透明度,
触控高光,
可触摸的本地反馈,
看法
滚动视图,
情态动词
领航员,
样式表,
尺寸,
本机模块
}从“反应本机”;
从'react redux'导入{connect};
从“./api/FeedAPI”导入{newFeed};
从“./actions/NewFeedAction”导入{showNewFeedPage};
//从'react native qiniu'导入{Auth,ImgOps,Conf,Rs,Rpc};
从“react native image crop picker”导入ImagePicker;
从“/util/Md5”导入Md5;
从“react native keyboard spacer”导入键盘间隔符;
从“./api/URLConf”导入URLConf;
从“/util/Secret”导入{getToken};
从“/util/Secret”导入机密;
const windowWidth=Dimensions.get('window').width;
const windowHeight=Dimensions.get('window').height;
常数裕度=20;
常数imgInterval=5;
常数imgCountLimit=9;
const textLengthLimit=140;
const PRE_URL=URLConf.API_HOST+/psu/;
const PUT_PRE_URL=PRE_URL+“PUT”;
const GET_PRE_URL=PRE_URL+“GET”;
类NewFeed扩展组件{
建造师(道具){
超级(道具);
此.state={
文本:“”,
图像:[],
imagesID:[]//上传图片返回的 散列id
标签:[]//已经添加的标签
标记:“”//正在输入的标签
tagCountLimit:5,
已上载:false,
是的,
真的,
透明:假,
};
}
cancle(){
this.props.showNewFeedPage(false);
this.props.callback();
}
pickMultiple(){
ImagePicker.openPicker({
多重:对,
maxFiles:imgCountLimit-this.state.images.length,
})。然后(图像=>{
var newImages=this.state.images;
images.map((i,索引)=>{
console.log('received image',i);
push({uri:i.path,width:i.width,height:i.height,mime:i.mime,index:index});
});
这是我的国家({
图片:新图片,
});
}).catch(e=>{});
}
genId(){//生成的ID可能已经存在,但可以在以后计划
返回“xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxx”。替换(/[xy]/g,函数(c){
var r=Math.random()*16 | 0,
v=c=='x'?r:(r&0x3 | 0x8);
返回v.toString(16);
}).toUpperCase();
}
上传(){//新上传!
if(this.state.images!==null&&this.state.images.length!=0){
//设formData=new formData();
for(让img知道这个.state.images){
让key=this.genId()+'.+img.mime.replace('image/','');
console.log('img upload key:'+key);
log('img.mime:'+img.mime);
设formData={
钥匙:钥匙,
};
//var psu=“”;
//首先从服务器获取一个预先签名的URL
//log('callbackfun:'+callback);
log('获取预先签名的url')
getToken((令牌)=>{
var path=PUT_PRE_URL+“/”+键;
var sign=Md5.hex_Md5(path.replace(URLConf.APP_SERVER_HOST.)+'?ts=123456&'+Secret.Secret);
console.log('sign:'+sign);
var url=path+'-ts=123456&sign='+sign;
日志(“url:+url”);
变量选项={
//方法:“POST”,
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”,
“X-Auth-Token”:标记,
}//,
//正文:encodeURI(JSON.stringify({objectKey:key}),'utf-8')
};
log('[GET]'+url);
获取(url、选项)
.then((response)=>response.json())
.然后((响应数据)=>{
console.log('[RTN]'+responseData);
log('[RTN]json字符串化:'+json.stringify(responseData));
var psu=responseData.data.url;
console.log('PSU:'+PSU);
如果(psu!==null){
//然后,一旦你预先签署了url,上传图片
const xhr=new XMLHttpRequest();
xhr.打开('PUT',psu);
xhr.onreadystatechange=函数(){
if(xhr.readyState==4){
如果(xhr.status==200){
log('图像成功上传到S3');
console.log(key+'upload success');
this.state.imagesID.push({key:key});
if(this.state.imagesID.length==this.state.images.length){
newFeed(this.state.text,this.state.imagesID,this.state.tags,(结果,id)=>{
如果(结果){
this.clearState();
}
});
}
}否则{
log('将映像发送到S3时出错');
log('XHR-ResponseText:'+XHR.ResponseText);
}
}
}
log(“图像uri:+img.uri”);
xhr.setRequestHeader('Content-Type',img.mime);//'image/jpeg'
send({uri:img.uri,type:img.mime,name:key});//name:'myimage.jpg'})