【问题标题】:React Native can't access this.props outside of render() methodReact Native 无法在 render() 方法之外访问 this.props
【发布时间】:2016-07-27 12:00:22
【问题描述】:

我试图在clicked() 方法中访问this.props,但它们是未定义的。如何通过 ListItemExample 类中的方法访问this.props

我的目标是将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();
  }

}

【问题讨论】:

  • 你的构造函数不应该把props作为参数传递给super吗? constructor(props) { super(props) }

标签: javascript reactjs react-native


【解决方案1】:

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

【讨论】:

  • 请添加更多详细信息或参考链接。
  • 你不应该在渲染中绑定方法,它会创建一个方法的实例并触发一个新的渲染。
  • 拯救了我的一天:D
  • 你应该提供解释
【解决方案2】:

随着 React 从 createClass 到 ES6 classes 的转变,我们需要自己处理 this 的正确值到我们的方法,如下所述:http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes 使用构造函数中的this.clicked = this.clicked.bind(this) 更改您的代码以使方法绑定到正确的构造函数中的 this 值

no autobinding 是 React 人员为 ES6 课程精心设计的一步。 React.createClass 提供了对正确上下文的自动绑定。可以在这里找到详细信息:https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

因此,基于此,您还可以将 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();
 }

}

【讨论】:

  • this.props 在这个例子中是未定义的,除非我遗漏了一些明显的东西。
  • 要修复“未定义”问题,请在您的构造函数中添加以下语句:this.clicked= this.clicked.bind(this);它将方法绑定到组件实例。希望对您有所帮助!
【解决方案3】:

添加bind(this) 以将您的方法绑定到当前组件,例如

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

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

【讨论】:

    【解决方案4】:

    在使用带有 React Native 的 FBSDK 时,我遇到了同样的问题。 @fandro 的回答几乎解释了很多。

    我有这个:

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

    this.props.onLoginSuccess() 的调用导致问题“未定义不是评估 this.props.onLoginSuccess() 的对象”。因此,当我将const infoRequest = new GraphRequest(...) 中的代码更改为包含.bind(this) 时:

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

    成功了。希望这会有所帮助。

    【讨论】:

      【解决方案5】:

      您可以为您的处理程序使用箭头函数并自动绑定到词法范围。 ...或在调用时或在您的构造函数中使用传统的 .bind(this) 。但请注意,我认为一个答案使用了这种方法:您必须更改 babel 设置并确保您有 "optional": ["es7.classProperties"] 以使类中的箭头函数正常工作。

      【讨论】:

      • 此答案缺少示例
      【解决方案6】:

      在您尝试进入另一个视图的组件中,您必须通过在导入组件的 onPress 中使用它来发送对象导航

      例子

      在视图中实现组件

      &lt;CardComponent title="bla bla" navigation={this.props.navigation} /&gt;

      组件模板

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

      此问题是因为您尝试实现的组件未在 stackNavigation 上定义,因此您无法使用方法导航,并且通过参数传递此对象导航器您可以访问它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-21
        • 2020-12-09
        相关资源
        最近更新 更多