Исключение компонента React Native: undefined не является объектом (вычисление ‘_this’)

#typescript #react-native

#typescript #react-native

Вопрос:

Я работаю над приложением для распознавания лиц, используя react native 0.63. Я запускаю свой проект с помощью react-native run-android . Я получаю исключение компонента undefined не является объектом (вычисление ‘_this’). Я новичок в react native и не понимаю значения этой ошибки. Я следую руководству по этому приложению, но оно очень старое, и поэтому я не могу обновить код до последней версии react native. Вот ссылка на учебное пособие по распознаванию лиц с использованием react native. Пожалуйста, посмотрите и решите мою проблему.

 import React from 'react';

import {StyleSheet,Text,View,Image} from 'react-native';
 
import NativeModules, { ImagePickerManager } from 'react-native';
 
import Button from './Button';
 
import RNFetchBlob from 'react-native-fetch-blob';
 
import _ from 'lodash';
 
const Detector = props => {

this.state = {
    photo_style: {
        position: 'relative',
        width: 480,
        height: 480
    },
    has_photo: false,
    photo: null,
    face_data: null
};

return (
  <View style={styles.container}>
     
    <Image
        style={this.state.photo_style}
        source={this.state.photo}
        resizeMode={"contain"}
    >
        { this._renderFaceBoxes.call(this) }
    </Image>
 
    <Button
        title="Pick Photo"
        onPress={()=>{this._pickImage.bind(this)}}
        button_styles={styles.button}
        button_text_styles={styles.button_text} />

    { this._renderDetectFacesButton.call(this) }

  </View>
);


}

  const _pickImage = () => {
 
this.setState({
    face_data: null
});

ImagePickerManager.showImagePicker(this.props.imagePickerOptions, (response) => {
     
  if(response.error){
    alert('Error getting the image. Please try again.');
  }else{
     
    let source = {uri: response.uri};

    this.setState({
      photo_style: {
        position: 'relative',
        width: response.width,
        height: response.height
      },
      has_photo: true,
      photo: source,
      photo_data: response.data
    });
     
  }
});



}
 
  const _renderDetectFacesButton = () => {
    if(this.state.has_photo){
        return  (
            <Button
                title="Detect Faces"
                onPress={()=>{this._detectFaces.bind(this)}}
                button_styles={styles.button}
                button_text_styles={styles.button_text} />
        );
    }
  }
 
  const _detectFaces = () => {
RNFetchBlob.fetch('POST', 'https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=trueamp;returnFaceAttributes=age,gender', {
    'Accept': 'application/json',
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': this.props.apiKey
}, this.state.photo_data)
.then((res) => {
    return res.json();      
})
.then((json) => {
     
    if(json.length){
        this.setState({
            face_data: json
        });
    }else{
        alert("Sorry, I can't see any faces in there.");
    }
     
    return json;
})
.catch (function (error) {
    console.log(error);
    alert('Sorry, the request failed. Please try again.'   JSON.stringify(error));
});
 



}
 
  const _renderFaceBoxes = () => {
if(this.state.face_data){

    let views = _.map(this.state.face_data, (x) => {
         
        let box = {
            position: 'absolute',
            top: x.faceRectangle.top,
            left: x.faceRectangle.left
        };

        let style = { 
            width: x.faceRectangle.width,
            height: x.faceRectangle.height,
            borderWidth: 2,
            borderColor: '#fff',
        };
         
        let attr = {
            color: '#fff',
        };

        return (
            <View key={x.faceId} style={box}>
                <View style={style}></View>
                <Text style={attr}>{x.faceAttributes.gender}, {x.faceAttributes.age} y/o</Text>
            </View>
        );
    });

    return <View>{views}</View>
}



 }
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    alignSelf: 'center',
    backgroundColor: '#ccc'
  },
  button: {
    margin: 10,
    padding: 15,
    backgroundColor: '#529ecc'
  },
  button_text: {
    color: '#FFF',
    fontSize: 20
  }
});
 
export default Detector 
  

введите описание изображения здесь

Ответ №1:

Ваш компонент определен как const Detector = props => { функциональный компонент. Функциональные компоненты не имеют «this» и не имеют таких методов, как setState или componentDidMount . Есть два способа решить вашу проблему.

  1. Либо вы создаете компонент, который наследуется от React.Component . Смотрите Документы. Когда вы это сделаете, this будут доступны, а также другие методы компонента, такие как this.setState .
  2. Или вы используете перехваты, например useState , для управления состоянием внутри ваших компонентов. Документы

Какой из них вы выберете, зависит от предпочтений, хотя hooks — это «более новый» способ выполнения действий.

Комментарии:

1. Спасибо @Thomas. Используйте React. Компонент решает мою проблему.

2. Теперь я получаю эту ошибку undefined is not an object(evaluating 'this._renderFaceBoxes.call') . Можете ли вы, пожалуйста, решить эту проблему?