2016-04-06 3 views
12

Ich versuche auf this.props in der clicked() Methode zuzugreifen, aber sie sind nicht definiert. Wie kann ich auf this.props über die Methoden in der ListItemExample-Klasse zugreifen?React Native kann nicht auf this.props außerhalb der render() -Methode zugreifen

Mein Ziel ist es, die id in der Show-Ansicht, die die Detailansicht für ein angeklickt ListItemExample zeigt.

export default class Example extends Component { 

    constructor() { 
    super(); 
    let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 

    this.state = { 
     dataSource: ds, 
     isLoading: true 
    }; 
    } 

    componentDidMount() { 
    this.fetchData() 
    } 

    fetchData() { 

    Api.getPosts().then((resp) => { 
     console.log(resp); 
     this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(resp.posts), 
     isLoading: false 
     }) 
    }); 

    } 

    render() { 
    return (
     <View style={styles.container}> 

      <ListView 
       dataSource={this.state.dataSource} 
       renderRow={this.renderRow.bind(this)} 
       style={styles.postList} 
       /> 

     </View> 
    ); 
    } 

    renderRow(post) { 
    return (
     <PostListItem 
      id={post.id} 
      coverImage={post.cover_image} 
      title={post.title} 
      lockedStatus={post.status} 
      time={post.time} /> 
    ); 
    } 

} 



export default class ListItemExample extends Component { 

    constructor() { 
    super(); 
    } 

    render() { 
    return (
     <TouchableHighlight onPress={this.clicked} > 
     <View style={styles.postItem}> 


     </View> 
     </TouchableHighlight> 
    ); 
    } 

    clicked() { 
    console.log("clicked props"); 
    console.log(this.props); 
    Actions.openPost(); 
    } 

} 
+1

Sollte Ihr Konstruktor nicht "Requisiten" als Argument nehmen und an Super übergeben? 'Konstruktor (Requisiten) {Super (Requisiten)}' – TAGraves

Antwort

15

Sie tun müssen: onPress = {this.clicked.bind (this)}

+3

Bitte fügen Sie weitere Details oder Verweis-Links hinzu. – eden

+0

Sie sollten keine Methoden im Render binden, es erzeugt eine Instanz der Methode und löst ein neues Rendering aus. –

7

Mit der Verschiebung der Reaktion von createClass zu ES6 classes wir auf den richtigen Wert von this unseren Methoden behandeln müssen unsere eigene, wie hier erwähnt: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes ändern Sie den Code die Methode zu haben, begrenzt Wert dieses in Konstruktor zu korrigieren ein bewusster Schritt von React Jungs für ES6 Klassen this.clicked = this.clicked.bind(this) in Ihrem Konstruktor

The no autobinding war. Autobinding zum korrekten Kontext wurde mit React.createClass bereitgestellt. Details hierzu finden sich hier: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

So auf dieser Basis auch Ihre clicked Methode ändern könnte wie:

export default class ListItemExample extends Component { 

constructor(props) { 
    super(props); 
} 

render() { 
    return (
    <TouchableHighlight onPress={this.clicked} > 
     <View style={styles.postItem}> 


     </View> 
    </TouchableHighlight> 
); 
} 

clicked =() => { 
    console.log("clicked props"); 
    console.log(this.props); 
    Actions.openPost(); 
} 

} 
+1

this.props ist in diesem Beispiel nicht definiert, es sei denn, ich vermisse etwas Offensichtliches. – botbot

0

ich gleiche Problem hatte bei der Verwendung von FBSDK mit React Ureinwohner. Und @fandro Antwort hat fast viel erklärt.

ich dies hatte:

render() { 
     const infoRequest = new GraphRequest(
      '/me', 
      null, 
      this.responseInfoCallback, 
     ); 

     return (
      <View> 
       <LoginButton 
        readPermissions={["email"]} 
        onLoginFinished={ 
         (error, result) => { 
          if (error) { 
           console.log("Login failed with error: " + result.error); 
          } else if (result.isCancelled) { 
           console.log("Login was cancelled"); 
          } else { 
           new GraphRequestManager().addRequest(infoRequest).start(1000); 
           console.log("Login was successful with permissions: " + result.grantedPermissions) 
          } 
         } 
        } 
        onLogoutFinished={() => alert("User logged out")}/> 
      </View> 
     ); 
    } 

responseInfoCallback(error, result) { 
     if (error) { 
      alert('Error fetching data: ' + error.toString()); 
     } else { 
      alert('Success fetching data: ' + result.toString()); 
      this.props.onLoginSuccess(); 
     } 
    } 

Und Aufruf von this.props.onLoginSuccess() verursachte Problem "nicht definiert ist kein Gegenstand der Bewertung this.props.onLoginSuccess()". Also, wenn ich den Code in const infoRequest = new GraphRequest(...) geändert umfassen .bind(this):

const infoRequest = new GraphRequest(
     '/me', 
     null, 
     this.responseInfoCallback.bind(this), 
    ); 

Es funktionierte. Hoffe das hilft.

6

hinzufügen bind(this) Ihre Methode in die aktuelle Komponente zu binden, wie

yourMethod(){ 
    console.log(this.props) 
}  

<SomeComponent onClick={this.yourMethod.bind(this)} /> 
0

Sie Pfeil Funktionen für Ihren Handler verwenden können und automatisch auf den lexikalischen Umfang zu binden. ... oder gehen Sie zum Zeitpunkt des Aufrufs oder in Ihrem Konstruktor in die herkömmliche .bind (this). Aber ich denke, eine Antwort verwendet diesen Ansatz: Sie müssen Ihre babel-Einstellungen ändern und sicherstellen, dass Sie "optional": ["es7.classProperties"] für Pfeilfunktionen in Klassen haben, damit sie ordnungsgemäß funktionieren.

Verwandte Themen