>  기사  >  웹 프론트엔드  >  React Event 이벤트 등록 구현

React Event 이벤트 등록 구현

不言
不言원래의
2018-07-20 11:22:001556검색

이 글에서는 React Event 이벤트 등록 구현에 대해 소개합니다. 필요한 친구가 참고할 수 있습니다.

React 요소의 이벤트 처리는 DOM 요소의 이벤트 처리와 매우 유사합니다. 하지만 약간의 문법적 차이가 있습니다.

  • React 이벤트 바인딩 속성은 소문자 대신 카멜 케이스로 이름이 지정됩니다.

  • JSX 구문을 사용하는 경우 문자열이 아닌 함수를 이벤트 핸들러로 전달해야 합니다(DOM 요소가 작성되는 방식)

그리고 React 자체는 React를 사용할 때 내부적으로 합성 이벤트를 구현합니다. , 일반적으로 이미 생성된 DOM 요소에 리스너를 추가하기 위해 addEventListener를 사용할 필요가 없습니다. 요소가 처음 렌더링될 때만 리스너를 제공하면 됩니다.

이것이 어떻게 구현되는지 살펴보겠습니다

React 이벤트 메커니즘은 이벤트 등록이벤트 배포, 두 부분으로 나누어집니다.

이벤트 등록

// 事件绑定
function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
}

  return (
    <a>
      Click me
    </a>
  );

위 코드에서 onClick은 다음과 같이 전달됩니다. props handlerClick은 컴포넌트가 업데이트되고 마운트되면 props를 처리합니다. 프로세스는 다음과 같습니다:
React Event 이벤트 등록 구현

핵심 코드:
ReactDOMComponent.js가 로드(mountComponent)되고 업데이트(updateComponent)될 때 를 호출합니다. props 처리 방법:_updateDOMProperties

ReactDOMComponent.js

_updateDOMProperties: function(lastProps, nextProps, transaction) {
...
if (registrationNameModules.hasOwnProperty(propKey)) {
        if (nextProp) {
          // 如果传入的是事件,去注册事件
          enqueuePutListener(this, propKey, nextProp, transaction);
        } else if (lastProp) {
          deleteListener(this, propKey);
        }
      } 
...
}

// 注册事件
function enqueuePutListener(inst, registrationName, listener, transaction) {
  var containerInfo = inst._nativeContainerInfo;
  var doc = containerInfo._ownerDocument;
    ...
    // 去doc上注册
  listenTo(registrationName, doc);
    // 事务结束之后 putListener
  transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
  });
}

바인딩 방법을 살펴보세요

ReactBrowserEventEmitter.js

listento

//registrationName:需要绑定的事件
//当前component所属的document,即事件需要绑定的位置
listenTo: function (registrationName, contentDocumentHandle) {
    var mountAt = contentDocumentHandle;
    //获取当前document上已经绑定的事件
    var isListening = getListeningForDocument(mountAt);
    ...
      if (...) {
      //冒泡处理  
      ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(...);
      } else if (...) {
        //捕捉处理
        ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(...);
      }
      ...
  },
결국 실제로는 doc.addEventLister(event, callback, false);

You 모든 이벤트가 문서에 바인딩되어 있음을 볼 수 있습니다

그래서 트리거된 이벤트는 ReactEventListener의 dispatchEvent 메서드입니다

Callback 이벤트 저장

listenerBank

react는 바인딩된 모든 이벤트의 콜백을 저장하기 위해 ListenerBank 변수를 유지합니다.

이전 이벤트 등록 방법으로 돌아가기

function enqueuePutListener(inst, registrationName, listener, transaction) {
  var containerInfo = inst._nativeContainerInfo;
  var doc = containerInfo._ownerDocument;
  if (!doc) {
    // Server rendering.
    return;
  }
  listenTo(registrationName, doc);
  transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
  });
}
putListener는 바인딩이 완료된 후 실행됩니다.

var listenerBank = {};
var getDictionaryKey = function (inst) {
//inst为组建的实例化对象
//_rootNodeID为组件的唯一标识
  return '.' + inst._rootNodeID;
}
var EventPluginHub = {
//inst为组建的实例化对象
//registrationName为事件名称
//listner为我们写的回调函数,也就是列子中的this.autoFocus
  putListener: function (inst, registrationName, listener) {
    ...
    var key = getDictionaryKey(inst);
    var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});
    bankForRegistrationName[key] = listener;
    ...
  }
}
EventPluginHub는 React당 한 번만 인스턴스화됩니다. 즉, 프로젝트 그룹의 모든 이벤트에 대한 콜백은 고유한 ListenerBank에 저장됩니다.

관련 권장 사항:

React 사용: React 구성 요소 내부의 상태 관리

위 내용은 React Event 이벤트 등록 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.