web-dev-qa-db-fra.com

cette valeur est nulle dans la fonction (React-Native)

Selon les tests locaux, "this" semble être nul dans la fonction de rendu de la ligne. En conséquence, cela m'empêche de lier une fonction locale sur l'accessoire onPress.

J'ai ce bloc de rendu:

render() {
    return (
        <ListView
            dataSource={this.state.dataSource}
            renderRow={this._renderRow}
            renderHeader={this._renderHeader} 
            style={styles.listView} />
    );
}

et une fonction locale

_visitEntryDetail() {
    console.log('test');
}

puis rendu en ligne

_renderRow(something) {
    return (
        <TouchableHighlight
            style={[styles.textContainer, filestyle.container]} 
            onPress={this._visitEntryDetail.bind(this)} >
            <View>
                <Text style={filestyle.text1} >{something.detail}</Text>
                <Text style={filestyle.text2} >{something.size}, {something.timestamp}</Text>
            </View>
        </TouchableHighlight>
    );
}

Cela retourne 

message: null is not an object (evaluating 'this.$FileList_visitEntryDetail')"

cocher "this" sur renderRow renvoie la valeur null lors du remplacement du code ci-dessus par:

_renderRow(file) {
    console.log(this);
    return (
        <TouchableHighlight
            style={[styles.textContainer, filestyle.filelistcontainer]} 
             >

avec la sortie suivante de la console:

RCTJSLog> null

mais c'est bien quand

render() {
    console.log('inside render. this value is below me');
    console.log(this);
    return (
        <ListView

console

RCTJSLog> "inside render. this value is below me"
RCTJSLog> [object Object]

Quelqu'un peut-il s'il vous plaît indiquer ce qui cause cela. Merci.

20
boredgames

this est null car _renderRow n'a pas été lié à la classe actuelle. S'il vous plaît gardez en tête:

Dans le constructeur, vous devez explicitement lier une fonction si vous souhaitez la transmettre à un composant de réaction, car parfois, elle ne se lie pas implicitement.

Cette déclaration s'applique à toute fonction transmise au composant. Par exemple, vous souhaitez appeler une fonction callThisFunction en appuyant sur TouchableHighlight. Vous pouvez le relier par:

class SomeComponent extends Component {

  constructor(props) {
    super(props)

    //binding function
    this.renderRow = this.renderRow.bind(this)
    this.callThisFunction = this.callThisFunction.bind(this)
  }

  renderRow() {
    console.log(this) //not null now
    return (
      <View>
        <TouchableHighlight onPress={this.callThisFunction}>
          <Image source={require('image!prev')}/>
        </TouchableHighlight>
      </View>
    )
  }

  callThisFunction() {
    console.log(this) //not null now
  }
}
47
NightFury

Une alternative à la solution de NightFury serait d'utiliser ES6 Arrow Function syntax sans devoir lier manuellement la fonction dans le constructeur. Votre render() ressemblerait alors à ceci:

render() {
    return (
       <ListView
           dataSource={this.state.dataSource}
           renderRow={() => this._renderRow()}
           renderHeader={() => this._renderHeader()} 
           style={styles.listView} />
    );
}
3
George

Si vous souhaitez transmettre une fonction à un composant tiers, transmettez toujours les fonctions de cette manière:

        <Carousel
          renderItem={item => this._renderItem(item)}
        />

Lorsque vous liez une fonction comme ça, il n'a pas perdu d'instance de fonction dans d'autres classes

0
Semih Fatih