2016-02-17 18 views
5

Reading this SO answer, tôi hiểu rằng khi tôi vượt qua một chức năng để một thành phần phản ứng, tôi phải ràng buộc một hàm trong các nhà xây dựng như thế nàyràng buộc một hàm được chuyển vào một thành phần

constructor(props) { 
    super(props); 

    //binding function 
    this.renderRow = this.renderRow.bind(this); 
    this.callThisFunction = this.callThisFunction.bind(this); 
    } 

hoặc tôi sẽ nhận được một lỗi như thế này

rỗng không phải là một đối tượng: đánh giá this4.functionName

Tiếp theo lời khuyên đó, tôi bị ràng buộc các chức năng trong các nhà xây dựng nhưng tôi vẫn nhận được cùng một lỗi.

Tôi đang thực hiện một ứng dụng Master/Detail với Phản ứng Native dựa trên ví dụ phim trong phản ứng repo bản địa, ngoại trừ việc tôi không sử dụng cú pháp này

var SearchScreen = React.createClass({ 

(mà là những gì các repo là) nhưng đúng hơn là cú pháp kiểu ES6 này

class ListOfLists extends Component { 

Trong chế độ xem danh sách của tôi, tôi vẽ một hàng như thế này.

class MovieList extends Component{ 
     constructor(props){ 
     super(props); 
     this.selectMovie = this.selectMovie.bind(this); 
     this.state = { 
      dataSource: new ListView.DataSource({ 
      rowHasChanged: (row1, row2) => row1 !== row2, 
      }), 
     }; 
     } 
      renderRow(
      movie: Object, 
      sectionID: number | string, 
      rowID: number | string, 
      highlightRowFunc: (sectionID: ?number | string, rowID: ?number | string) => void, 
     ) { 
      console.log(movie, "in render row", sectionID, rowID); 
      return (
       <ListCell 
       onSelect={() => this.selectMovie(movie)} 
       onHighlight={() => highlightRowFunc(sectionID, rowID)} 
       onUnhighlight={() => highlightRowFunc(null, null)} 
       movie={movie} 
       /> 
      ); 
      } 

     selectMovie(movie: Object) { 
     if (Platform.OS === 'ios') { 
      this.props.navigator.push({ 
      title: movie.name, 
      component: TodoListScreen, 
      passProps: {movie}, 
      }); 
     } else { 
      dismissKeyboard(); 
      this.props.navigator.push({ 
      title: movie.title, 
      name: 'movie', 
      movie: movie, 
      }); 
     } 
     } 
    render(){ 
     var content = this.state.dataSource.getRowCount() === 0 ? 
      <NoMovies /> : 
      <ListView 
      ref="listview" 
      renderSeparator={this.renderSeparator} 
      dataSource={this.state.dataSource} 
      renderFooter={this.renderFooter} 
      renderRow={this.renderRow} 
      automaticallyAdjustContentInsets={false} 
      keyboardDismissMode="on-drag" 
      keyboardShouldPersistTaps={true} 
      showsVerticalScrollIndicator={false} 
      renderRow={this.renderRow} 
    } 

Dòng khóa là this.selectMovie(movie). Khi tôi bấm một hàng với một tên phim, tôi nhận được một lỗi

rỗng không phải là một đối tượng: evaluating this4.selectMovie

Câu hỏi: tại sao nó nói với tôi null is not an object hay đúng hơn là tại sao là chức năng null?

Cập nhật:

tôi thêm render phương pháp để mã để hiển thị nơi renderRow được làm quen

+0

Tôi không thể nhìn thấy nơi bạn sử dụng 'renderRow' nhưng bạn có thể cần phải ràng buộc nó. Tuy nhiên bạn không cần phải kết hợp các chức năng mũi tên và ràng buộc. – sodik

+0

@sodik Tôi cập nhật OP để hiển thị nơi 'renderRow' được sử dụng – Leahcim

Trả lời

9

Cách để giải quyết vấn đề này mà không sửa đổi mã của bạn rất nhiều là thêm this.renderRow = this.renderRow.bind(this) vào hàm tạo lớp của bạn.

class New extends Component{ 
    constructor(){ 
    this.renderRow = this.renderRow.bind(this) 
    } 

    render(){...} 
} 

bạn có thêm tài sản renderRow = { this.renderRow }, Trong thực tế, renderRow thực hiện với binded to null object .Try để an ủi this trong renderRow bạn sẽ thấy nó là GlobalObject thay vì Class MovieList mà bạn mong muốn.

+1

Tôi có thể bị nhầm lẫn, nhưng đây thực sự là giải pháp thích hợp cho vấn đề này?Câu trả lời không giải thích nguyên nhân gây ra vấn đề ngay từ đầu, và nó có vẻ như là một hack. – Felipe

+0

@PixelCakeGames Cảm ơn bạn đã tìm ra câu trả lời chưa được đưa ra lúc đầu, trong khi tôi không phải đây là 'hack' thay vì giải pháp. Rõ ràng là phương thức renderRow được thực thi chiều rộng ràng buộc với đối tượng 'null' và đó là điều mà @Leahcim gặp phải. –

1

Hãy thử sử dụng cú pháp es6:

selectMovie = (movie) => { 
    if (Platform.OS === 'ios') { 
    this.props.navigator.push({ 
     title: movie.name, 
     component: TodoListScreen, 
     passProps: {movie}, 
    }); 
    } else { 
    dismissKeyboard(); 
    this.props.navigator.push({ 
     title: movie.title, 
     name: 'movie', 
     movie: movie, 
    }); 
    } 
} 

và sau đó

constructor(props) { 
    super(props); 

    this.selectMovie = this.selectMovie(); 
    this.state = { 
    dataSource: new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
    }) 
    }; 
} 

renderRow = (...) => { 
    return (
    <ListCell 
     onSelect={this.selectMovie(movie)} 
     onHighlight={() => highlightRowFunc(sectionID, rowID)} 
     onUnhighlight={() => highlightRowFunc(null, null)} 
     movie={movie} 
    /> 
); 
} 
Các vấn đề liên quan