2

私の最初のファイル open.jsx で言うと、次のようになります。

    // Default Import Statements here

var open = React.createClass({

  render() {
    return (
      <div>
        <Dialog
          title="Test"
          ref="openDialog">
        </Dialog>
      </div>
    );
  },
  _handleTouchTap() {
    this.refs.openDialog.setState({open:true});
  }
});

module.exports = open;

そして、私の app.jsx ファイルには次のものがあります。

const testComponent = React.createClass({
    render() {
    return (
          <FlatButton label="Test" onTouchTap={this._handleTouchTap}/>
    );
  },

  _handleTouchTap: function() {
    Open._handleTouchTap();
  }
});

module.exports = testComponent;

現在発生しているエラーは次のとおりです。 Uncaught TypeError: Open._handleTouchTap is not a function

React のファイル間でメソッドを渡す方法を知っている人はいますか?

open.jsx's _handleTouchTap()でボタンを押したときにメソッドを呼び出したいapp.jsx

4

2 に答える 2

0

ボタンを含むページをレンダリングし、誰かが FlatButton を押すとすぐにダイアログを表示するとします。また、Material-ui を使用していることに気付きましたので、それで行きましょう。

React プロジェクトを開始するときは、コンポーネントの階層について考えることをお勧めします。material-ui を使用しており、Dialog コンポーネントの開始は props を渡すことによって制御されているため、次のアプローチを使用するのが最も簡単です。

シンプルなケース

ボタンをマウントし、ダイアログをマウントするルート コンポーネント アプリ (app.jsx 内) を使用しますが、ダイアログは最初は非表示の状態 (Dialog の「open」プロップはデフォルトで false) であるため、まだ視覚的に表示されません。 (マウントされているにもかかわらず)。この場合、ボタンが押されたらすぐに、Dialog の open prop を true に設定する必要があります。

このレンダリングのほとんどを個別のコンポーネントに分離することをお勧めします。説明のために、すべてを App.jsx に保持しましょう。

この場合の整理方法は次のとおりです。

// App.jsx (render + handle click function only)
render: function() {
  return (
      <div>
          <FlatButton label="Test" onTouchTap={this._handleTapTestButton}/>
          <Dialog
            title="Test"
            open={this.state.dialogOpen}>
            <div>My dialog contents</div>
          </Dialog>
      </div>
  );
},
_handleTapTestButton: function() {
  this.setState({dialogOpen: !this.state.dialogOpen}); // flip the state
}

見る?refs も必要ありません (それは良いことです!)。これで、Dialog コンポーネントが FlatButton の近くに適切に配置されている場合、これは正常に機能します。

より複雑なケース: ダイアログが FlatButton から遠く離れている

次の質問は、「Dialog コンポーネントが、 App.jsx コンポーネントの子でも親でもなく、まったく異なるコンポーネントの奥深くにネストされている場合、どうすればこれを整理できますか?」

うーん、これは私には少しにおいがします(単なる意見です)。これはアンチパターン自体ではありませんが、これを回避できる場合は、そうすることをお勧めします。つまり、あなた自身の利便性と保守性のために、相互に自然に相互作用するコンポーネントを (親子の観点から) コンポーネント階層内で互いに近くに保つようにしてください。このようにして、小道具を使用して非常に簡単に通信できます (これについては React の情報を参照してください。これは絶対的な規則ではありませんが、それから逸脱する理由はたくさんあります。

それをしない正当なケースがあると仮定しましょう。さらに悪いことに、コンポーネントは兄弟であり、直接または間接の祖父母/親/子ではありません。

その場合、次の 2 つのオプションがあります。

  • ストアと関連するイベント (または状態を伝達するその他の JavaScript コード) を使用して、状態の変化を他のコンポーネントに伝達します (つまり、Flux、Redux、または好みのものを使用します)。この場合、ボタンがクリックされると、他のコンポーネントによって取得されるどこかでイベントが発生します。このイベントは、他のコンポーネントの状態変更をトリガーします。警告: これは、Flux や Redux のような状態管理フレームワークが存在する理由の 1 つです。
  • または、onTouchTap で、共有の親コンポーネントから渡された関数を FlatButton に呼び出させます。次に、この関数は共有親コンポーネントで状態を反転し、この状態をプロパティとしてダイアログに渡します。つまり、両方のコンポーネントがどこかで祖父母を共有している場合、祖父母レベルで関数を定義し、その関数を小道具として FlatButton に渡すことができます。関数の役割は、親の親の状態を変更することです (dialogOpen)。この状態は、1 つまたは複数のコンポーネントに prop として階層のずっと下に渡され、最終的に Dialog に到達します。これは、prop が true に切り替わると自動的に表示されます。

どちらのアプローチにも重大な利点/欠点があります。最初のアプローチでは、UI レンダリング ロジックがストアにリークされ (通常は避けられませんが、Flux などを使用して管理できます)、2 番目のアプローチではコンポーネント階層にリークされ (メンテナンスの点でトリッキーです)、密結合が発生する傾向があります (yuck)。 .

于 2015-12-28T08:40:51.497 に答える