2016-11-23 119 views
0

如何在React Native中綁定超出範圍的函數?我發現了錯誤:未定義不是評估this.state/this.props的對象

undefined is not an object evaluating this.state 

&

undefined is not an object evaluating this.props 

我使用的渲染方法時的數據加載勾起renderGPSDataFromServer()。問題是,我試圖在renderGPSDataFromServer()裏面使用_buttonPress()calcRow(),但是我收到了這些錯誤。

我添加

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

我的構造,我已經改變了_buttonPress() {_buttonPress =() => {,仍然一無所獲。

我想我明白這個問題,但我不知道如何解決它:

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> 
    ) 
}}; 

如何去修復這一點,在這種情況下,是什麼問題?

回答

1

這是因爲發生,map方法裏面的函數創建一個不同的上下文。您可以使用箭頭函數作爲map方法中的回調來進行詞法綁定。這應該解決你遇到的問題。

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> 
 
    ); 
 
    }); 
 
    }

而且,一旦你在類函數定義中使用箭頭的功能,你 不需要將它們綁定在構造函數中,如:

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

而且,一旦你定義的類用作箭頭功能,你 不需要使用箭頭功能,而美其名曰之一:

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

不知道這是否是問題,但我認爲是代碼錯誤,並可能導致您的問題。

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

明確此行onPress={this._buttonPress().bind(this)}> 要調用的函數,並同時結合了。

正確的方式做這將是如此

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

這樣的函數將被調用僅onPress。

0

您正朝着正確的方向發展,但仍然存在一個小問題。您正在將function傳遞給map回調,該回調具有與您的組件不同的範圍(this)(因爲它不是箭頭函數),所以當您執行bind(this)時,您正在重新綁定回調以使用範圍map。我認爲這應該起作用,它基本上將你傳遞給map的回調變成箭頭函數。此外,由於你bind您在構造函數中,你不需要再做了:

// 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

我也認爲你應該遵循皮內達的建議,關於如何處理我完全忽略了我的答案的道具。 – martinarroyo

2

this.props是隻讀的

React docs - component and props

並因此組件不應該嘗試對它們進行修改更不用說變異他們爲你在這裏做:

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

我建議使用狀態,而不是:

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

關於您的綁定問題:

.map方法採用第二個參數,用於在回調被調用時設置this的值。

在您的問題的上下文中,您只需要通過this作爲第二個參數.map方法將組件範圍的this綁定到它。

相關問題