92

CustomEvent親ノードと通信するために、通常の DOM を作成してリッスンしています。

子供の場合:

  var moveEvent = new CustomEvent('the-graph-group-move', { 
    detail: {
      nodes: this.props.nodes,
      x: deltaX,
      y: deltaY
    },
    bubbles: true
  });
  this.getDOMNode().dispatchEvent(moveEvent);

親で:

componentDidMount: function () {
  this.getDOMNode().addEventListener("the-graph-group-move", this.moveGroup);
},

これは機能しますが、より良い React 固有の方法はありますか?

4

6 に答える 6

53

上記のように:

React の方法は、props — を介して明示的にコールバックを子に渡すことです。React ではバブリングを伴うカスタム イベントはサポートされていません。

リアクティブ プログラミングの抽象化は直交しています。

オブザーバー パターンを使用した対話型システムのプログラミングは難しく、エラーが発生しやすいですが、依然として多くの運用環境で実装標準となっています。リアクティブプログラミングの抽象化を支持して、オブザーバーを徐々に非推奨にするアプローチを提示します。いくつかのライブラリ レイヤーは、プログラマーが既存のコードをコールバックからより宣言的なプログラミング モデルにスムーズに移行するのに役立ちます。

React の哲学は代わりに Command パターンに基づいています。

ここに画像の説明を入力

参考文献

于 2014-03-12T22:50:29.150 に答える
8

簡単なサービスを作成して使用できます

/** eventsService */
module.exports = {
  callbacks: {},

  /**
   * @param {string} eventName
   * @param {*} data
   */
  triggerEvent(eventName, data = null) {
    if (this.callbacks[eventName]) {
      Object.keys(this.callbacks[eventName]).forEach((id) => {
        this.callbacks[eventName][id](data);
      });
    }
  },

  /**
   * @param {string} eventName name of event
   * @param {string} id callback identifier
   * @param {Function} callback
   */
  listenEvent(eventName, id, callback) {
    this.callbacks[eventName][id] = callback;
  },

  /**
   * @param {string} eventName name of event
   * @param {string} id callback identifier
   */
  unlistenEvent(eventName, id) {
    delete this.callbacks[eventName][id];
  },
};

例(トリガーも同様)

import eventsService from '../../../../services/events';
export default class FooterMenu extends Component {
  componentWillMount() {
    eventsService
      .listenEvent('cart', 'footer', this.cartUpdatedListener.bind(this));
  }

  componentWillUnmount() {
    eventsService
      .unlistenEvent('cart', 'footer');
  }

  cartUpdatedListener() {
    console.log('cart updated');
  }
}
于 2018-03-05T18:48:15.323 に答える
5

コンテキストを介して渡されたコールバックを介してイベントをバブルアップできます: [CodePen]

import * as React from 'react';

const MyEventContext = React.createContext(() => {});

const MyEventBubbleContext = ({children, onMyEvent}) => {
  const bubbleEvent = React.useContext(MyEventContext);
  const handleMyEvent = React.useCallback((...args) => {
    // stop propagation if handler returns false
    if (onMyEvent(...args) !== false) {
      // bubble the event
      bubbleEvent(...args);
    }
  }, [onMyEvent]);
  return (
    <MyEventContext.Provider value={handleMyEvent}>
      {children}
    </MyEventContext.Provider>
  );
};

const MyComponent = () => (
  <MyEventBubbleContext onMyEvent={e => console.log('grandparent got event: ', e)}>
    <MyEventBubbleContext onMyEvent={e => console.log('parent got event: ', e)}>
      <MyEventContext.Consumer>
        {onMyEvent => <button onClick={onMyEvent}>Click me</button>}
      </MyEventContext.Consumer>
    </MyEventBubbleContext>
  </MyEventBubbleContext>
);

export default MyComponent;
于 2016-04-23T21:39:46.920 に答える
3

私が見つけた別のものがあります。これは、特に親から子へと穴をあけるのがすでに面倒になっている場合に非常に合理的です。彼はそれを単純でないコミュニケーションと呼びました。リンクは次のとおりです。

https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md

于 2015-05-12T04:48:04.747 に答える
3

ReactJs アプリで Observer パターンに絶対に頼る必要がある場合は、通常のイベントを乗っ取ることができます。たとえば、delete キー<div>で削除のマークが付けられた を発生させたい場合<div>は、customEvent によって呼び出される keydown イベントをリッスンすることができます。body で keydown をトラップcustomEventし、選択した で keydown イベントをディスパッチし<div>ます。誰かに役立つ場合に備えて共有します。

于 2016-02-12T13:26:33.957 に答える