2016-11-23 2 views
0

Wie binde ich eine Funktion außerhalb des Gültigkeitsbereichs in React Native? Ich erhalte die Fehler:Nicht definiert ist kein Objekt, das dies auswertet.state/this.props

undefined is not an object evaluating this.state 

&

undefined is not an object evaluating this.props 

ich die Render-Methode bin mit renderGPSDataFromServer() hervorzurufen, wenn die Daten geladen wurde. Das Problem ist, ich versuche, _buttonPress() und calcRow() innerhalb von renderGPSDataFromServer() zu verwenden, aber ich bekomme diese Fehler.

Ich habe

hinzugefügt
constructor(props) { 
    super(props); 
    this._buttonPress = this._buttonPress.bind(this); 
    this.calcRow = this.calcRow.bind(this); 

meinen Konstruktor und ich habe _buttonPress() { zu _buttonPress =() => { und immer noch nichts geändert.

Ich glaube, ich verstehe das Problem, aber ich weiß nicht, wie es zu beheben:

renderLoadingView() { 
    return (
     <View style={[styles.cardContainer, styles.loading]}> 
      <Text style={styles.restData}> 
       Loading ... 
      </Text> 
     </View> 
    ) 
} 

_buttonPress =() => { 
    this.props.navigator.push({ 
     id: 'Main' 
    }) 
} 

renderGPSDataFromServer =() => { 
    const {loaded} = this.state; 
    const {state} = this.state; 

    return this.state.dataArr.map(function(data, i){ 
     return(
      <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}> 
       <View style={styles.cardContentLeft}> 
        <TouchableHighlight style={styles.button} 
         onPress={this._buttonPress().bind(this)}> 
         <Text style={styles.restData}>View Video</Text> 
        </TouchableHighlight> 
       </View> 

      <View style={styles.cardContentRight}> 
      <Text style={styles.restData}>{i}</Text> 
      <View style={styles.gpsDataContainer}> 
       <Text style={styles.gpsData}> 
       {Number(data.lat).toFixed(2)}</Text> 
       <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text> 
      </View> 
      <Text style={styles.gpsData}> 
      {this.calcRow(55,55).bind(this)} 
      </Text> 
      </View> 
     </View> 
    ); 
    }); 
} 

render =()=> { 
    if (!this.state.loaded) { 
     return this.renderLoadingView(); 
    } 
    return(
     <View> 
     {this.renderGPSDataFromServer()} 
     </View> 
    ) 
}}; 

Wie gehe ich über diese Festsetzung und in diesem Fall, was das Problem ist?

Antwort

1

Dies geschieht, weil die Funktion innerhalb der map Methode erzeugt einen anderen Kontext. Sie können Pfeilfunktionen als Callback in der Methode map für die lexikalische Bindung verwenden. Das sollte das Problem lösen, das Sie haben.

renderGPSDataFromServer =() => { 
 

 
    const {loaded} = this.state; 
 
    const {state} = this.state; 
 

 
    return this.state.dataArr.map((data, i) => { 
 
     return(
 
     <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}> 
 

 
      <View style={styles.cardContentLeft}> 
 
      <TouchableHighlight style={styles.button} 
 
      onPress={this._buttonPress().bind(this)}> 
 
      <Text style={styles.restData}>View Video</Text> 
 
      </TouchableHighlight> 
 
      </View> 
 

 
      <View style={styles.cardContentRight}> 
 
      <Text style={styles.restData}>{i}</Text> 
 
      <View style={styles.gpsDataContainer}> 
 
       <Text style={styles.gpsData}> 
 
       {Number(data.lat).toFixed(2)}</Text> 
 
       <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text> 
 
      </View> 
 
      <Text style={styles.gpsData}> 
 
      {this.calcRow(55,55).bind(this)} 
 
      </Text> 
 
      </View> 
 

 
     </View> 
 
    ); 
 
    }); 
 
    }

Auch, wenn Sie Pfeil Funktionen in der Klasse Funktionsdefinition verwendet haben Sie nicht brauchen, sie in Konstruktor zu binden, wie:

constructor(props) { 
 
    super(props); 
 
    this._customMethodDefinedUsingFatArrow = this._customMethodDefinedUsingFatArrow.bind(this) 
 
}

Auch, wenn Sie Klassenfunktionen wie Pfeilfunktionen definiert haben, Sie müssen nicht mit den Pfeil Funktionen nutzen, während sie ruft entweder:

class Example extends React.Component { 
 
    myfunc =() => { 
 
    this.nextFunc() 
 
    } 
 

 
    nextFunc =() => { 
 
    console.log('hello hello') 
 
    } 
 

 
    render() { 
 
    // this will give you the desired result 
 
    return (
 
     <TouchableOpacity onPress={this.myFunc} /> 
 
    ) 
 
    
 
    // you don't need to do this 
 
    return (
 
     <TouchableOpacity onPress={() => this.myFunc()} /> 
 
    ) 
 
    } 
 
}

0

nicht sicher, ob dies das Problem ist, aber ich denke, dass Code falsch ist, und möglicherweise Ihr Problem verursacht.

<View style={styles.cardContentLeft}> 
    <TouchableHighlight style={styles.button} 
    onPress={this._buttonPress().bind(this)}> 
    <Text style={styles.restData}>View Video</Text> 
    </TouchableHighlight> 
</View> 

speziell diese Linie onPress={this._buttonPress().bind(this)}> Sie die Funktion aufgerufen wird und es zugleich zu binden.

Der richtige Weg, dies zu tun, so würde

onPress={this._buttonPress.bind(this)}> 

auf diese Weise die Funktion aufgerufen wird, onPress nur.

0

Sie gehen in die richtige Richtung, aber es ist immer noch ein kleines Problem. Sie übergeben eine function an Ihre map Callback mit einem anderen Bereich (this) als Ihre Komponente (weil es keine Pfeilfunktion ist), also wenn Sie bind(this) tun, binden Sie Ihren Rückruf zurück, um den Bereich von map zu verwenden. Ich denke, das sollte funktionieren, es verwandelt den Callback, den Sie an map übergeben, grundsätzlich in eine Pfeilfunktion. Auch da Sie bind Ihre Funktion im Konstruktor, Sie brauchen es nicht wieder tun:

// The constructor logic remains the same 
    // .... 
    renderLoadingView() { 
     return (
     <View style={[styles.cardContainer, styles.loading]}> 
     <Text style={styles.restData}> 
      Loading ... 
     </Text> 
     </View> 
    ) 
    } 

    _buttonPress =() => { 
     this.props.navigator.push({ 
     id: 'Main' 
     }) 
    } 

    renderGPSDataFromServer =() => { 

    const {loaded} = this.state; 
    const {state} = this.state; 

    return this.state.dataArr.map((data, i) => { 
     return(
     <View style={[styles.cardContainer, styles.modularBorder, styles.basePadding]} key={i}> 

      <View style={styles.cardContentLeft}> 
      <TouchableHighlight style={styles.button} 
      onPress={this._buttonPress}> 
      <Text style={styles.restData}>View Video</Text> 
      </TouchableHighlight> 
      </View> 

      <View style={styles.cardContentRight}> 
      <Text style={styles.restData}>{i}</Text> 
      <View style={styles.gpsDataContainer}> 
       <Text style={styles.gpsData}> 
       {Number(data.lat).toFixed(2)}</Text> 
       <Text style={styles.gpsData}>{Number(data.long).toFixed(2)}</Text> 
      </View> 
      <Text style={styles.gpsData}> 
      {this.calcRow(55,55).bind(this)} 
      </Text> 
      </View> 

     </View> 
    ); 
    }); 
    } 

    render =()=> { 
    if (!this.state.loaded) { 
     return this.renderLoadingView(); 
    } 
    return(
     <View> 
     {this.renderGPSDataFromServer()} 
     </View> 
    ) 
    }}; 
+1

Ich denke auch, dass Sie Pinedas Rat befolgen sollten, wie man mit Requisiten umgeht, die ich auf meiner Antwort völlig übersehen habe. – martinarroyo

2

this.props sind schreibgeschützt

React docs - component and props

Und deshalb sollte eine Komponente nicht versuchen, sie allein mutieren sie ändern lassen, wie Sie hier tun werden:

_buttonPress =() => { 
     this.props.navigator.push({ 
     id: 'Main' 
     }) 
    } 

schlage ich würde Zustand anstelle:

_buttonPress =() => { 
    this.setState = { 
    ...this.state, 
    navigator: { 
     ...this.state.navigator, 
     id: 'Main' 
    } 
    } 
} 

In Bezug auf Ihr Bindungsproblem:

die .map Methode verwendet ein zweites Argument, das verwendet wird, um den Wert this festzulegen, wenn der Rückruf aufgerufen wird.

Im Zusammenhang mit Ihrer Frage müssen Sie nur this als 2. Argument an Sie .map Methode übergeben, um den Komponentenbereich this an ihn zu binden.

Verwandte Themen