2015-02-05 14 views
7

Tôi có mô-đun React hoạt động tốt trong ES5. Tôi đang chuyển đổi nó thành ES6 và sử dụng 6to5 để chuyển đổi. Tất cả mọi thứ transpiles tốt, nhưng tôi nhận được một lỗi thời gian chạy khi tôi đang cố gắng để thiết lập của tôi props. Khi tôi thả một số debugger và xem this, tôi thấy rằng thisEventEmitter chứ không phải lớp. Đây là mã của tôi:Cách giải quyết `this` trong việc chuyển đổi mô-đun React thành lớp ES6

var React = require('react'); 

import CalendarStore from './../stores/calendar.store.js'; 

function getAppointments() { 
    return {appts: CalendarStore.getAppts()} 
} 

export default class extends React.Component{ 
    constructor(props) { 
    super(props); 
    this.props = { 
     view: 'weeks' 
    } 
    } 

    changeView(child, view) { 
    this.setProps({view: view}); 
    } 

    componentWillMount() { 
    CalendarStore.addChangeListener(this._onChange); 
    } 

    _onChange() { 
    this.setProps(getAppointments()); 
    } 

    .... 
}; 

Địa điểm tôi gặp sự cố nằm trong chức năng changeView. Khi nó là transpiled xuống nó trông như thế này:

_onChange: { 
     value: function _onChange() { 
     this.setProps(getAppointments()); 
     }, 
     writable: true, 
     configurable: true 
    } 

Một lần nữa, bên trong hàm, thisEventEmitter tôi. Cách sửa lỗi này là gì?

Trả lời

16

this.setProps không được dùng nữa, hãy sử dụng trạng thái cho điều này. Báo cáo này sẽ cung cấp cho bạn cảnh báo này trong 0.13:

Cảnh báo: setProps (...) không được chấp nhận trong các lớp Phản hồi JavaScript đơn giản.

Phương pháp lớp học es6 cũng không tự động, vì vậy bạn cần phải liên kết thủ công theo cách thủ công. Bạn có thể sử dụng .bind(this) hoặc sử dụng các chức năng mũi tên. Tuy nhiên, đối với các trình phát bên ngoài, bạn cần phải tham khảo.

Bạn chỉ có thể thoát khỏi _onChange:

this._calendarListener = e => this.setState({things: e}); 
CalendarStore.addChangeListener(this._calendarListener); 

Hoặc ràng buộc trong các nhà xây dựng:

constructor(props){ 
    ... 
    this._onClick = this._onClick.bind(this); 
} 

Đừng quên để unbind sự kiện trong componentWillUnmount:

componentWillUnmount(){ 
    CalendarStore.removeChangeListener(this._onClick); 
    // or 
    CalendarStore.removeChangeListener(this._calendarListener); 
} 

Thêm trình lắng nghe sự kiện phải được thực hiện trong componentDidMount, không phải componentWillMount. Hàm tạo thay thế componentWillMount trong các lớp es6.

Mã này là rất xấu ... bạn đang trọng các đạo cụ phản ứng bộ:

this.props = { 
    view: 'weeks' 
} 

Chỉ cần thay thế tất cả các lần xuất hiện của 'đạo cụ' với 'nhà nước' trong mã của bạn, và tất cả sẽ được tốt. Ngoài ra, bạn có thể muốn trạng thái ban đầu của cửa hàng.

this.state = { 
    view: 'weeks', 
    things: CalendarStore.getAppts() 
} 

Ngoài ra, createClass sẽ không đi bất cứ lúc nào sớm, vì vậy cảm thấy tự do để tiếp tục sử dụng nó. Nó thường đơn giản hơn. Cửa hàng nói chung nên được xử lý bởi mixins, đó là tầm thường với createClass, nhưng khó khăn hơn để làm ngay trong các lớp học es6. Tôi có một thư viện nhỏ cho mixins with react and es6 classes.

+0

Bạn có thể chỉ cho tôi một blog hoặc một nơi nào đó giải thích cách cửa hàng nên được xử lý bởi mixin không? – jhamm

+0

Hầu hết các triển khai thông lượng cung cấp một. Mixin xử lý trạng thái ban đầu từ cửa hàng, nghe cửa hàng và thực hiện điều này.setState khi có thay đổi. Nó cũng làm sạch người nghe khi các thành phần được unmounted. Đây là một ví dụ về một [mixux cửa hàng mixin] (http://fluxxor.com/documentation/store-watch-mixin.html) – FakeRainBrigand

+0

@FakeRainBrigand nếu tôi cũng sử dụng lưu lượng và đặt giá trị mặc định như thế này thì sao? '_handleStoreChange = (state: Object = {}) => {..}' Tôi nhận được một lỗi cú pháp với babel 'Gán cho rvalue' – tsm

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