Custom.js для обмена сообщениями с родительскими узлами

Я делаю и слушаю обычный DOM CustomEvent для связи с родительскими узлами:

У ребенка:

  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);
},

Это работает, но есть ли конкретный вариант, который будет лучше?

Ответ 1

Как отмечено выше:

Реагирование будет заключаться в том, чтобы передать обратные вызовы детям напрямую через реквизиты -. Там нет поддержки пользовательских событий с пузырьками в React.

Абстракция реактивного программирования ортогональна:

Программирование интерактивных систем с помощью шаблона наблюдателя является трудным и подверженным ошибкам, но по-прежнему является стандартом внедрения во многих производственных средах. Мы представляем подход к постепенному обесцениванию наблюдателей в пользу абстракций реактивного программирования. Несколько слоев библиотеки помогают программистам плавно переносить существующий код из обратных вызовов на более декларативную модель программирования.

Философия React основана на шаблоне Command:

введите описание изображения здесь

Ссылки

Ответ 3

Вы можете написать простой сервис, а затем использовать его

/** 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');
  }
}

Ответ 4

Возможное решение, если вы абсолютно должны обратиться к шаблону Observer в приложении ReactJs, вы можете захватить нормальное событие. Например, если вы хотите, чтобы ключ удаления вызывал <div>, который помечен для удаления, вы могли бы прослушать <div> событие keydown, которое будет вызываться customEvent. Ловушка на клавиатуре и отправьте событие customEvent keydown на выбранном <div>. Совместное использование в случае, если это поможет кому-то.

Ответ 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;

Ответ 6

Центральное хранилище [Redux], которое распределяет состояние по клиентам, которое затем "отправляет" состояние обратно в хранилище, похоже на шаблон наблюдателя. Способ делать публикацию/подписку только хуже из-за явных (хрупких?) Накладных расходов, соединяющих пути реквизитов/событий. Чтобы разобраться в иерархии, React предоставляет контекст (шаблон поставщика) или наблюдаемые библиотеки, которые воняют. Как MobX, который вводит новые декораторы @observable, или Vue, который вводит новый синтаксис шаблона "v-if". Событие - это основной способ работы цикла событий DOM и JavaScript, так почему бы и нет? Я думаю, что сатанисты сделали это. Лол

Ответ 7

Я понимаю, что этот вопрос уже довольно старый, но этот ответ все еще может кому-то помочь. Я написал JSX-прагму для React, которая добавляет декларативное настраиваемое событие: jsx-native-events.

По сути, вы просто используете onEvent<EventName> для отслеживания событий.

<some-custom-element onEventSomeEvent={ callback }></some-custom-element>