2016-11-01 17 views
2

私は、ES6クラスが基本的にES5オブジェクトシステムのまわりの構文的砂糖であるという印象を受けています。 私はトランスファーなしでReactを実行しようとしているので、React.Componentから "継承する"オブジェクト "クラス"を定義するために古い構文を使用することができると考えました。Reactで「通常の」ES5プロトタイプ継承を実装する方法は?

var Board = function(props, state) { 
     var instance = {}; 

     instance.props = props; 
     instance.context = state; 

     return(instance);   
    }; 

    Board.prototype = Object.create(React.Component.prototype); 

    Board.prototype.render = function() { 
     return(
      // ...stuff 
     )    
    }; 

しかし、それは動作しません!

react.js:20478 Warning: Board(...): No `render` method found on the returned component instance: you may have forgotten to define `render` 
react.js:6690 Uncaught TypeError: inst.render is not a function(…) 

私は選択肢in this gist、および以下の作品が見つかりました:

var Board = function(props, state) { 
     var instance = Object.create(React.Component.prototype); 

     instance.props = props; 
     instance.context = state; 

     instance.prototype.render = function() { 
      return(
       // ...stuff 
      )    
     }; 

     return(instance);   
    }; 

私はReact.createClassヘルパーを使用できることも見出しました。

しかし、Reactがこのような一般的な方法で定義されたクラスを処理しない理由を理解したいと思います。 ES6クラスは使用前にインスタンス化されているようです。 ES5スタイルのクラスもインスタンス化されない理由はなく、同様の結果が得られます。

+3

作成し、コンストラクタで 'instance'変数を返さないでください。代わりに 'this'を使用し、何も返しません。 (最初のスニペットでやっていることは、本当にES5のクラスを正しく行っていないのです。) – Frxstrem

+1

私は人々がこの質問をd​​ownvoteしないことを望みます。受け入れられた答えは、私が簡単にウェブ上で見つけることができなかったいくつかの情報と明確な例を提供します。これは、私が作ったエラーにもかかわらず、 "旧式の"オブジェクトを使ってReactを使ってみようとする人にとって、有益な質問かもしれません。 – Rolf

+0

あなたはこの回答を見ているかもしれません:https://stackoverflow.com/questions/43529107/how-does-prototypal-inheritance-in-javascript-really-works –

答えて

5

「正常」なES5 prototypal継承がReactでサポートされていないのはなぜですか?

React.createClassはおそらくあなたのより良い選択です。あなたの質問にあるコードは、標準のES5クラスのような継承タスクを実行していないということだけです。特に:

  • あなたはプレーンなオブジェクトではなく、Boardのインスタンスのインスタンスを返していて、とてもBoard.prototypeは、オブジェクトによって使用されていません。通常、コンストラクタ関数は何も返さないはずであり、呼び出すときにオブジェクトnewを作成する必要があります。このオブジェクトはthisという名前で受け取ります。
  • React.Componentにインスタンスを初期化する機会が与えられていません。
  • Board.prototypeにはconstructorが設定されていません(ただし、私はリアクションが関心を持っているかどうかはわかりませんが、多くはそうではありません)。

通常の方法で設定すると機能します。ここでReact.createClassなしES5の例だ、コメントを参照してください。

// The component 
 
function Foo(props) { 
 
    // Note the chained superclass call 
 
    React.Component.call(this, props); 
 
} 
 

 
// Set up the prototype 
 
Foo.prototype = Object.create(React.Component.prototype); 
 
Foo.prototype.constructor = Foo; // Note 
 

 
// Add a render method 
 
Foo.prototype.render = function() { 
 
    return React.createElement("div", null, this.props.text); 
 
}; 
 

 
// Use it 
 
ReactDOM.render(
 
    React.createElement(Foo, { 
 
     text: "Hi there, the date/time is " + new Date() 
 
    }), 
 
    document.getElementById("react") 
 
);
<div id="react"></div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

+0

私は最初の例を正しく実装していない。しかし、これは以前の試みから進化してきたもので、どちらの場合でもうまくいきませんでした。あなたの答えは、コンストラクタ内の親クラスへの呼び出しのような貴重な(欠落した)情報を含んでいるようです。 私は 'Foo.prototype = Object.create(React.Component。プロトタイプ); 'Foo = Object.create(React.Component.prototype);ではありません。 – Rolf

+0

http://codepen.io/anon/pen/wowKJP – Rolf

+1

ありがとうございます。 – Rolf

関連する問題