简体   繁体   English

React Native 无法在 render() 方法之外访问 this.props

[英]React Native can't access this.props outside of render() method

I am trying to access this.props in the clicked() method, but they are undefined.我试图在clicked()方法中访问this.props ,但它们是未定义的。 How can I access this.props through the methods in the ListItemExample class?如何通过 ListItemExample 类中的方法访问this.props

My goal is to maintain the id into the show view that shows the detail view for a clicked ListItemExample.我的目标是将id维护到显示单击 ListItemExample 的详细视图的显示视图中。

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

}

你需要做onPress={this.clicked.bind(this)}

With the shift of React from createClass to ES6 classes we need to handle the correct value of this to our methods on our own, as mentioned here: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes Change your code to have the method bounded to correct value of this in constructor using this.clicked = this.clicked.bind(this) in your constructor随着的转变,从createClass反应ES6 classes我们需要处理的正确值this我们对我们自己的方法,这里提到: http://www.newmediacampaigns.com/blog/refactoring-react-components-to- es6-classes在构造函数中使用this.clicked = this.clicked.bind(this)更改您的代码以将方法绑定到构造函数中的 this 的正确值

The no autobinding was a deliberate step from React guys for ES6 classes. no autobinding是 React 人员为 ES6 类故意no autobinding的步骤。 Autobinding to correct context was provided with React.createClass . React.createClass 提供了React.createClass绑定到正确的上下文。 Details of this can be found here: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding详情请见: https : //facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

So based on this you could also change your clicked method as:因此,基于此,您还可以将clicked方法更改为:

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

}

Add bind(this) to binding your method into current component, like添加bind(this)以将您的方法绑定到当前组件中,例如

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

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

I had same issue when using FBSDK with React Native.将 FBSDK 与 React Native 一起使用时,我遇到了同样的问题。 And @fandro answer almost did explain a lot. @fandro 的回答几乎解释了很多。

I had this:我有这个:

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

And call of this.props.onLoginSuccess() caused issue "undefined is not an object evaluating this.props.onLoginSuccess()".并调用this.props.onLoginSuccess()导致问题“未定义不是评估 this.props.onLoginSuccess() 的对象”。 So when I changed the code in const infoRequest = new GraphRequest(...) to include .bind(this) :因此,当我更改const infoRequest = new GraphRequest(...)的代码以包含.bind(this)

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

It worked.它奏效了。 Hope this helps.希望这会有所帮助。

You can use arrow functions for your handlers and bind to the lexical scope automagically.您可以为处理程序使用箭头函数并自动绑定到词法范围。 ... or go down the traditional .bind(this) at invocation time or in your constructor. ...或者在调用时或在您的构造函数中使用传统的 .bind(this) 。 But note, as I think one answer uses this approach: you must change your babel settings and ensure you have "optional": ["es7.classProperties"] for arrow functions in classes to work properly.但请注意,因为我认为一个答案使用这种方法:您必须更改 babel 设置并确保您有“可选”:["es7.classProperties"] 类中的箭头函数才能正常工作。

In then compnent that you're trying enter to another view you must send the object navigation by you use this in the onPress of component imported在您尝试进入另一个视图的组件中,您必须通过在导入的组件的 onPress 中使用它来发送对象导航

example例子

Implementing component in a view在视图中实现组件

<CardComponent title="bla bla" navigation={this.props.navigation} />

Component template组件模板

`<View>
       <Button  title={this.props.title} onPress={()=> 
       this.props.navigation.navigate("anotherAwesomeView")}/>
</View>`

This problem is because the component that you're trying implement is not defined on stackNavigation, and by this the methot navigation is not avalible for you, and passing this object navigator by params you'll can access to it此问题是因为您尝试实现的组件未在 stackNavigation 上定义,因此您无法使用方法导航,并且通过 params 传递此对象导航器您可以访问它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM