developer tip

부모 노드와 통신하기위한 react.js 커스텀 이벤트

copycodes 2020. 11. 12. 08:25
반응형

부모 노드와 통신하기위한 react.js 커스텀 이벤트


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 전용 방법이 있습니까?


위에서 언급 한대로 :

React 방식은 props를 통해 명시 적으로 자식에게 콜백을 전달하는 것입니다. React에서 버블 링이있는 사용자 지정 이벤트는 지원되지 않습니다.

반응 형 프로그래밍 추상화는 직교합니다.

관찰자 패턴을 통한 대화 형 시스템 프로그래밍은 어렵고 오류가 발생하기 쉽지만 여전히 많은 프로덕션 환경에서 구현 표준입니다. 우리는 반응 형 프로그래밍 추상화를 위해 관찰자를 점차적으로 비난하는 접근 방식을 제시합니다. 여러 라이브러리 레이어는 프로그래머가 기존 코드를 콜백에서보다 선언적인 프로그래밍 모델로 원활하게 마이그레이션하는 데 도움이됩니다.

React 철학은 대신 명령 패턴을 기반으로합니다.

여기에 이미지 설명 입력

참고 문헌


간단한 서비스를 작성하고 사용할 수 있습니다.

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

특히 부모에서 자식으로 구멍을 뚫는 것이 이미 번거로울 경우 매우 합리적이라는 또 다른 발견이 있습니다. 그는 그것을 덜 단순한 의사 소통이라고 불렀습니다. 링크는 다음과 같습니다.

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


컨텍스트를 통해 전달 된 콜백을 통해 이벤트를 버블 링 할 수 있습니다. [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;

A possible solution, if you absolutely must resort to the Observer pattern in a ReactJs app you can hijack a normal event. For example, if you want the delete key to cause a <div> that is marked for deletion, you could have the <div> listen for a keydown event which will be invoked by a customEvent. Trap the keydown on the body and dispatch a customEvent keydown event on the selected <div>. Sharing in case it helps someone.


A central store [Redux] that distributes state to clients, that then 'dispatch' state back up to the store is like an observer pattern too. A way of doing publish/subscribe only worse because of explicit (brittle ?) overhead connecting props/events paths. To hack down through hierarchy React provides context (provider pattern) or observable libraries that stink. Like MobX that introduces new decorators @observable, or Vue that introduces new template syntax "v-if". Event's are the primary way DOM and javascript event loop work anyway, so why not ? I think the satanists did it. Lol


I realize this question is quite old by now, but this answer might still help someone. I've written a JSX pragma for React that adds declarative custom event: jsx-native-events.

기본적으로 onEvent<EventName>패턴을 사용하여 이벤트를 감시합니다.

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

참고 URL : https://stackoverflow.com/questions/21951734/react-js-custom-events-for-communicating-with-parent-nodes

반응형