2014-12-01 23 views
7

Lưu ý: Bài đăng này đã được đăng tại thời điểm React KHÔNG hỗ trợ ES6 (v12).Thừa kế React và ES6

Tôi có một lớp ES6:

class BaseClass { 
    getInitialState(){ 
     return {message: 'Hello!'}; 
    } 

    render() { 
     return (
      <div> 
       <div>{this.state.message}</div> 
      </div> 
     ) 
    } 
} 

Rằng tôi có thể xuất khẩu trong ES6 sử dụng biểu thức này (nguồn: react ES6 browserify)

export default React.createClass(BaseClass.prototype) 

này hoạt động tốt. Bây giờ tôi muốn sử dụng ES6 thừa kế để mở rộng BaseClass lớp học của tôi:

class ExtendedClass extends BaseClass{ 
    getInitialState(){ 
     return {message: "Hello! I'm an extension"}; 
    } 
} 

Nhưng khi tôi gọi React.createClass trên lớp ExtendedClass, tôi đã ngoại lệ sau đây:

Invariant Violation: ReactCompositeComponentInterface: You are attempting to define `constructor` on your component more than once. This conflict may be due to a mixin. 

Tôi biết Phản ứng 0,13 được coi ES6 thân thiện hơn nhưng có cách nào để xử lý điều đó không?

EDIT:

Tôi đang sử dụng Traceur để biên dịch lớp ES6 tôi. Đầu ra cho ExtendedClass trông giống như:

function ExtendedClass() { 
    "use strict"; 
    if (BaseClass !== null) { 
    BaseClass.apply(this, arguments); 
    } 
} 
for (BaseClass____Key in BaseClass) { 
    if (BaseClass.hasOwnProperty(BaseClass____Key)) { 
     ExtendedClass[BaseClass____Key] = BaseClass[BaseClass____Key]; 
    } 
    } 
    ____SuperProtoOfBaseClass = BaseClass === null ? null : BaseClass.prototype; 
    ExtendedClass.prototype = Object.create(____SuperProtoOfBaseClass); 
    ExtendedClass.prototype.constructor = ExtendedClass; 
    ExtendedClass.__superConstructor__ = BaseClass; 
    ExtendedClass.prototype.getInitialState = function() { 
    "use strict"; 
    return {message: "Hello! I'm an extension"}; 
    }; 
    React.createClass(ExtendedClass.prototype); 
+0

getInitialState không nên được sử dụng với mã es6. Thay vào đó, thiết lập trạng thái ban đầu của bạn trong hàm tạo, 'hàm tạo (đạo cụ) {super (đạo cụ); this.state = {message: 'Hello!'}} ' – widged

+0

Bài đăng này đã được đăng tại thời điểm React KHÔNG hỗ trợ ES6 (v12). Nó không còn liên quan nữa. Tất nhiên với React v13 tất cả mọi thứ hoạt động tốt và không cần phải sử dụng workaround đề cập đến. – JBE

Trả lời

1

Đây là workaround tôi đã tìm thấy:

Bên React.js thư viện, tôi đã cập nhật các ReactCompositeComponentInterface để thêm một chính sách tùy chỉnh cho constructor (Theo như tôi biết không có cách nào để tùy chỉnh 'giao diện' này đúng):

var ReactCompositeComponentInterface = { 

/** 
* An array of Mixin objects to include when defining your component. 
* 
* @type {array} 
* @optional 
*/ 
mixins: SpecPolicy.DEFINE_MANY, 

/** 
* Custom policy for 'constructor' 
*/ 
constructor: SpecPolicy.DEFINE_MANY, 

    ... 

} 

Sau đó, trong ExtendedClass, bạn phải xác định lại mọi phương pháp ngay cả khi bạn không tùy biến chúng:

class ExtendedClass extends BaseClass{ 
    getInitialState(){ 
     return {message: "Hello! I'm an extension"}; 
    } 
    /** required */ 
    render(){ 
     return super.render(); 
    } 
} 

Tôi không hài lòng với giải pháp dơ bẩn này nhưng nó sẽ thực hiện công việc chờ phiên bản 0.13 hy vọng sẽ giải quyết được những vấn đề đó.

6

Có một bài đăng tuyệt vời về cách viết ReactJS trong ES6.

http://ilikekillnerds.com/2015/02/developing-react-js-components-using-es6/

Dù sao khi sử dụng ES6 bạn không sử dụng React.createClass. bạn chỉ cần tạo lớp mở rộng React.Component

Cũng trong ES6 bạn không có getInitialState không phải là mặc địnhProps. nó được thay thế bằng cách sử dụng this.state bên trong constructor.

Xem ví dụ này. Giả sử bạn có thành phần Thẻ và Bảng điều khiển chào mừng mở rộng thành phần Thẻ.

Mã này là như sau: Component

thẻ:

import React , { Component } from 'react' 
class Card extends Component { 
    constructor(props){ 
    super(props); 
    } 

    render() { 
    return (
     <div className="card"> 
      <div className="card__content"> 
      <label>{this.props.content}</label> 
      </div> 
     </div> 
    ) 
    } 

    initPanel(el,content){ 
    React.render(<Card content={content} />, el); 
    } 
} 

export default Card; 

Chào mừng Bảng điều chỉnh phần:

import React from 'react'; 
import Card from 'components/card.component'; 

class WelcomePanel extends Card { 
    constructor(props){ 
    super(props); 
    this.state = { 
     content: "Welcome Panel", 
     index: 0 
    } 
    } 

    componentClicked(){ 
    this.setState({content: "Component Clicked", index: this.state.index + 1}) 
    } 

    render() { 
    return (
     <div className="welcome-panel" onClick={this.componentClicked.bind(this)}> 
     <Card content={`${this.state.content} ${this.state.index > 0 ? this.state.index : ''} ${this.state.index > 0 ? 'times' : ''} `} /> 
     </div> 
    ) 
    } 

    initPanel(el,content){ 
    React.render(<WelcomePanel />, el); 
    } 
} 

export default { Class: WelcomePanel }