2016-04-06 15 views
12

Tôi đang cố gắng truy cập this.props theo phương thức clicked(), nhưng chúng không được xác định. Làm thế nào tôi có thể truy cập this.props thông qua các phương pháp trong lớp ListItemExample?React Native không thể truy cập this.props bên ngoài phương thức render()

Mục tiêu của tôi là duy trì id vào chế độ xem chương trình hiển thị chế độ xem chi tiết cho một ListItemExample được nhấp.

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

Không nên người xây dựng của bạn lấy 'đạo cụ' làm đối số và chuyển nó sang siêu? 'constructor (props) {super (props)}' – TAGraves

Trả lời

15

Bạn cần phải làm: onPress = {this.clicked.bind (this)}

+3

Vui lòng thêm chi tiết hoặc liên kết tham chiếu. – eden

+0

Bạn không bao giờ nên ràng buộc các phương thức trong render, nó tạo ra một cá thể của phương thức và kích hoạt một render mới. –

7

Với sự thay đổi của Phản ứng từ createClass để ES6 classes chúng ta cần để xử lý các giá trị chính xác của this với các phương pháp của chúng tôi trên riêng của chúng tôi, như đã đề cập ở đây: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes Thay đổi mã của bạn để có phương pháp giáp để sửa giá trị của điều này trong constructor sử dụng this.clicked = this.clicked.bind(this) trong constructor của bạn

các no autobinding là một bước đi thận trọng từ Phản ứng kẻ cho các lớp ES6. Tự động sửa ngữ cảnh được cung cấp với React.createClass. Chi tiết này có thể được tìm thấy ở đây: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

Vì vậy, dựa trên điều này, bạn cũng có thể thay đổi phương thức clicked của bạn như:

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 là không xác định trong ví dụ này, trừ khi tôi đang thiếu một cái gì đó hiển nhiên. – botbot

0

tôi đã cùng một vấn đề khi sử dụng FBSDK với Phản ứng Native. Và câu trả lời @fandro gần như đã giải thích rất nhiều.

Tôi có điều này:

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

Và tiếng gọi của this.props.onLoginSuccess() vấn đề gây ra "không xác định không phải là một đối tượng đánh giá this.props.onLoginSuccess()". Vì vậy, khi tôi thay đổi mã trong const infoRequest = new GraphRequest(...) để bao gồm .bind(this):

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

Nó hoạt động. Hi vọng điêu nay co ich.

6

Thêm bind(this) để ràng buộc phương pháp của bạn thành phần hiện tại, giống như

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

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

Bạn có thể sử dụng chức năng mũi tên để xử lý của bạn và liên kết với phạm vi từ vựng cách tự động. ... hoặc đi xuống .bind truyền thống (này) tại thời gian yêu cầu hoặc trong nhà xây dựng của bạn. Nhưng lưu ý, như tôi nghĩ một câu trả lời sử dụng phương pháp này: bạn phải thay đổi cài đặt babel của mình và đảm bảo bạn có "tùy chọn": ["es7.classProperties"] cho các chức năng mũi tên trong lớp để hoạt động chính xác.

Các vấn đề liên quan