1. 程式人生 > >React Native 的 ES6 類寫法與未定義錯誤

React Native 的 ES6 類寫法與未定義錯誤

ES6, 即ECMAScript6, JavaScript的新標準, 書寫更加規範, 程式碼更加優雅. React Native推薦使用ES6的類寫法代替傳統的模組, 即使用extends React.Component代替React.createClass. 本文介紹在ReactNative中ES6的寫法, 與傳統方法進行對比, 並解決未定義(undefined)錯誤.

ES6

在ES6中, 一定要注意this的使用, 否則undefined is not an object.

模組定義

在ES6中, RN模組使用class形式, 代替var形式, 使程式碼更加規範.舊的寫法, 方法或變數使用逗號(“,”)

間隔.

var Feed = React.createClass({});

ES6的寫法, 方法或變數結束使用分號(“;”).

class Feed extends Component {}

引入匯出

引入使用import Story from './Story.js';

替換var Story = require('./Story');

匯出使用export default Feed;

替換module.exports = Feed;

初始化狀態

在ES6中, 使用class類的形式, 因此初始化在構造器(constructor)中進進行. 舊的寫法, 使用getInitialState

, 使用return返回狀態.

var Feed = React.createClass({
  getInitialState() {
    return {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2
      }),
      loaded: false,
      isAnimating: true,
      isRefreshing: false
    };
  }
});

ES6的寫法, 使用constructor

構造器, 直接設定state狀態.

class Feed extends Component {
  constructor(props) {
    super(props);
    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2
      }),
      loaded: false,
      isAnimating: true,
      isRefreshing: false
    }
  }
}

this繫結

在ES6中, 注意this的作用域, 由於使用類的寫法, 所以this僅僅指代當前的類, 對於內部類需要重新指定this, 指定位置可以任選. 舊的方式直接寫, 使用傳遞的props屬性.

var Feed = React.createClass({
  // 直接使用this.props屬性
  renderStories(story) {
    return (
      <Story story={story} navigator={this.props.navigator}></Story>
    );
  }

  render() {
    return (
      <ListView
        testID={"Feed Screen"}
        dataSource={this.state.dataSource}
        renderRow={this.renderStories}
        .../>
    )
  }
});

ES6的寫法. 在內部類中, 需要重新繫結this. 三種實現方式: 構造時, 呼叫時, 使用時.

class Feed extends Component {
  // 構造器直接繫結方法.
  constructor(props) {
    super(props);
    this.renderStories = this.renderStories.bind(this);
  }
}
class Feed extends Component {
  // 呼叫時, 繫結this.
  render() {
    return (
      <ListView
        testID={"Feed Screen"}
        dataSource={this.state.dataSource}
        renderRow={(story) => this.renderStories(story)}
        .../>
    )
  }
}
class Feed extends Component {
  // 使用時, 繫結this
  render() {
    return (
      <ListView
        testID={"Feed Screen"}
        dataSource={this.state.dataSource}
        renderRow={this.renderStories.bind(this)}
        .../>
    )
  }
}

注意繫結this失敗, 會發生未定義錯誤, 即undefined is not an object.

錯誤資訊

Error

React Native推薦使用ES6的語法規範開發, 因此在開發中, 我們儘量使用ES6. 使用類的形式, 對於編輯器更加友好, 也更容易實現自動索引, 方便程式設計.

感謝我的朋友前端大神@左大師的指導!

另外參考

OK, that’s all! Enjoy it!