wake-up-neo.com

React Native kann nicht auf this.props außerhalb der render () - Methode zugreifen

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

Mein Ziel ist es, die id in der Showansicht beizubehalten, die die Detailansicht für ein angeklicktes 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();
  }

}
17
botbot

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

27
fandro

Mit der Verschiebung von React von createClass zu ES6 classes müssen wir den korrekten Wert von this auf unsere eigenen Methoden anwenden, wie hier erwähnt: http://www.newmediacampaigns.com/blog/refactoring-react-components-to -es6-classes Ändern Sie Ihren Code so, dass die Methode im Konstruktor auf den korrekten Wert dieses Werts beschränkt ist, indem Sie this.clicked = this.clicked.bind(this) in Ihrem Konstruktor verwenden

Der no autobinding war ein bewusster Schritt von React Jungs für ES6-Klassen. Die Anbindung an den richtigen Kontext wurde mit React.createClass versehen. Details dazu finden Sie hier: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

Darauf basierend könnten Sie auch Ihre clicked-Methode wie folgt ändern:

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

}
8
Aditya Singh

Fügen Sie bind(this) hinzu, um Ihre Methode in die aktuelle Komponente zu binden, z 

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

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

Sie können Pfeilfunktionen für Ihre Handler verwenden und automatisch an den lexikalischen Bereich binden. ... oder gehen Sie die traditionelle .bind (this) zur Aufrufzeit oder in Ihrem Konstruktor herunter. Beachten Sie jedoch, dass eine Antwort diesen Ansatz verwendet: Sie müssen Ihre Babel-Einstellungen ändern und sicherstellen, dass Sie "optional" haben: ["es7.classProperties"], damit die Pfeilfunktionen in Klassen ordnungsgemäß funktionieren.

1
Ooki Koi

Ich hatte das gleiche Problem bei der Verwendung von FBSDK mit React Native. Und die Antwort von @fandro hat fast viel erklärt.

Ich hatte folgendes:

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

Der Aufruf von this.props.onLoginSuccess() verursachte das Problem "undefined ist kein Objekt, das this.props.onLoginSuccess () auswertet". Wenn ich also den Code in const infoRequest = new GraphRequest(...) geändert habe, um .bind(this) einzuschließen:

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

Es funktionierte. Hoffe das hilft.

0
Array