2017-03-12 20 views
1

Reactコンポーネントのコンストラクタで引数としてオブジェクトを渡しています。私は、コンストラクタでこれに結合する方法についていくつかの記事を読んで、私は、私は渡されたオブジェクトの関数を呼び出すいてUncaught TypeError:***はReactコンポーネントの関数ではありません

Uncaught TypeError: _this.layout.getWbsLayout is not a function 
    at new Wbs (Wbs.tsx:50) 
    at react-dom.js:4749 
    at measureLifeCyclePerf (react-dom.js:4529) 
    at ReactCompositeComponentWrapper._constructComponentWithoutOwner (react-dom.js:4748) 
    at ReactCompositeComponentWrapper._constructComponent (react-dom.js:4734) 
    at ReactCompositeComponentWrapper.mountComponent (react-dom.js:4642) 
    at Object.mountComponent (react-dom.js:11542) 
    at ReactCompositeComponentWrapper.performInitialMount (react-dom.js:4825) 
    at ReactCompositeComponentWrapper.mountComponent (react-dom.js:4712) 
    at Object.mountComponent (react-dom.js:11542) 

:その後、私は、オブジェクトの機能のいずれかを呼び出したいが、このエラーメッセージが表示されます議論として、私はここにこれが当てはまるとは確信しておらず、依然としてbind is not a functionという似たようなメッセージがあります。

私のコードは、Wbsがルートのリアクションコンポーネントです。WbsLayoutは、Wbsのコンストラクタのパラメータとして渡すオブジェクトです。

コンストラクタでエラーが発生したときthis.layout.getWbsLayout() 代わりにComponentDidMountで関数を呼び出しようとしましたが、同じエラーが発生しました。ここで

import * as React from 'react'; 
import WbsLayout from "../layout/WbsLayout"; 

interface WbsProps {} 
interface WbsState { 
    wbsElements: any[]; 
    wbsEdges: any[] 
} 

class Wbs extends React.Component<WbsProps, WbsState>{ 

    public cy: Cy.Instance; 
    private layout: WbsLayout; 
    private s: snap.Paper; 
    private renderer: WbsRenderer; 

    public state : WbsState; 

    constructor(props: WbsProps, layout: WbsLayout) { 
     super(props); 
     this.layout = layout; 
     this.cy = this.layout.cy; 

     // this does show a json object in the console, hence layout can be accessed 
     console.log(layout.cy.elements().jsons()); 

     this.layout.getWbsLayout(); //The error happens here 

     // initial state 
     this.state = { 
      wbsElements: [], 
      wbsEdges: [], 
     }; 
    } 

    public render() { 

     const wbsElements: any = this.state.wbsElements.map((element: any) => (
      <WbsElement 
       key={element.wbsElementBox.nodeId} 
       wbsElementBox={...element.wbsElementBox} 
       wbsElementTitle={...element.wbsElementTitle} 
       wbsElementId={...element.wbsElementId} 
      /> 
     )); 

     const wbsEdges: any = this.state.wbsEdges.map((edge: any) => (
      <WbsEdge 
       key={edge.edgeId} 
       edgeId={edge.edgeId} 
       sourceWbsElementData={...edge.sourceWbsElementData} 
       targetWbsElementData={...edge.targetWbsElementData} 
      /> 
     )); 

     return (
      <svg> 
       {wbsElements} 
       {wbsEdges} 
      </svg> 
     ); 
    } 
} 

export default Wbs; 

WbsLayoutです: コンソール:私はWBS'コンストラクタでJSONオブジェクトを見ることができます

let graph: any = { 
    nodes: [], 
    edges: [] 
}; 

let layout: WbsLayout = new WbsLayout(graph); 
let wbs = new Wbs(null, layout); 

エクスポートクラスWbsLayout {

public cy: Cy.Instance; 

    constructor(graph: any, Options?: Options) { 

     this.cy = cytoscape({ 
      headless: true, 
      elements: graph 
     }); 

    } 

    public getWbsLayout(): any { 
     const wbsElements: any = this.cy.collection("node[visibility = 'visible']").map((n: Cy.CollectionNodes) => 
      ({ 
       wbsElementBox: { 
        nodeId: n.data().id, 
        x: n.data().x, 
        y: n.data().y, 
        width: n.data().width, 
        height: n.data().height 
       }, 
       wbsElementTitle: { 
        text: n.data().title 
       }, 
       wbsElementId: { 
        text: n.data().wbsId 
       } 
      }) 
     ); 

     const wbsEdges: any = [ 
      { 
       edgeId: '5', 
       sourceWbsElementData: { 
        nodeId: '1', 
        x:464.359375, 
        y:30, 
        width:100, 
        height:40, 
        layoutStyle: 0 
       }, 
       targetWbsElementData: { 
        nodeId:'1.5', 
        x:867.875, 
        y:100, 
        width:130.84375, 
        height:40, 
        layoutStyle: 1 
       } 

      } 
     ]; 

     return { 
      wbsElements, 
      wbsEdges 
     }; 
    } 

    .... 
} 
export default WbsLayout; 

は、ここで私はWBSをインスタンス化する方法です.log(layout.cy.elements()。jsons());

+0

レンダリングで 'wbsElements'と' wbsEdges'関数を実行するべきだと考えてください – Li357

+0

おそらく 'React.createElement'はコンポーネントをインスタンス化するときにコンストラクタに' WbsLayout'インスタンスを渡さないからです。 – Li357

+0

どのように 'layout'をコンストラクタに渡していますか?あなたが何かを渡したいのであれば、 'props'を使ってやります。 –

答えて

0

EDIT:問題は無関係であることが判明しましたが、Reactがコンポーネントのテストを行い、状況が悪い場合に警告や警告を発するという点で、例えば、小道具が期待どおりに入らない場合など、「見てください」。初期の警告は時々であるので、はあなたの通常のデバッグ本能を捨てることができるという意味で役立ちます。


オリジナルの答え:

どちらの小道具が渡されたか、ダミーまたはフォールバック機能の動作のいくつかの種類をデフォルト設定の小道具を設定します前に、実行中の関数呼び出しを遮蔽します。コンストラクタで

if (this.layout.getWbsLayout) { 
    this.layout.getWbsLayout(); 
} 

その他のオプション:

  • 機能のデフォルト値を定義します。
  • 必要に応じてcomponentWillMountまたはcomponentDidMountで関数を実行します。ライフサイクルフックは、データのインスタンス化を実行するのに最適な場所です。コンストラクタは、必要に応じてクラスの関数をバインドするような状態呼び出しと静的呼び出しに最適です。
+0

同じエラーが発生しても、componentDidMount内で呼び出しを試みましたが、同じエラーが発生しました:componentDidMount(){ let layout:any = this.layout.getWbsLayout(); this.setState( {wbsElements:layout.wbsElements、 wbsEdges:layout.wbsEdges })。 } –

+0

'if 'アプローチを試しましたか?' typeof'を見てテストをより具体化することさえできました。私は長期的なアプローチではありませんが、問題の根本原因を絞り込むのに役立ちます。また、問題を再現するのに必要な最低限のコードを、ここでは最低限に抑えることも役に立ちます。ここにはたくさんのコードがありますが、関連すると思われる約5-10行しかありませんが、それ以上のことはありません。 –

+0

あなたの助けに感謝ベン。 NitzanとAndrewが上記のように、基本的には、私がconsole.logにレイアウトできても、パスされませんでした。私はちょっとリファクタリングし、代わりに小道具を使ってレイアウトを渡しました。今は魅力のように機能します。 Btw、あなたのアドバイスに従って、componentWillMountで自分のデータインスタンス化を実行する。 –

0

ありがとうございました。最初のヒントは正しかった:私はwbsコンストラクタにレイアウトを正常に渡していると思ったが、私はそうではなかった。 私は小道具内にレイアウトを含めるように自分のコードをリファクタリングしました。

関連する問題