react 의 떨 림 방지 와 절 류 는 큰 사람 이 포장 하 는 방법 을 사용 하면 시원 합 니 다. - 우리 같이 소스 코드 를 읽 습 니 다.
19533 단어 리 액 트 세트
큰 놈 의 바퀴 를 쓰 고 싶 지 않 으 면 직접 써 도 됩 니 다. 이 블 로 그 를 보 세 요. 자 바스 크 립 트 떨 림 방지 와 절 류 – 바퀴 를 만 드 는 것 은 향 기 롭 지 않 습 니까?
사내 의 바퀴 는 두 걸음 이면 사용 할 수 있다.
import React, { Component } from 'react';
import { throttle, debounce } from 'throttle-debounce';//1. throttle
export default class Children extends Component {
constructor(props) {
super(props);
/**
* 2.
* @param {number} 2000
*/
this.onClick = throttle(2000, this.onClick);
this.state = {
}
}
render() {
return (
<div>
<button onClick={this.onClick}> </button>
</div>
)
}
onClick = (e) => {
console.log('e', e);
}
}
위 는 react 가 큰 사내 패 키 징 을 개발 하 는 방법 으로 사용 하기에 매우 편리 합 니 다. 두 걸음 만 있 으 면 됩 니 다.
throttle
공부 하 다
그 다음 에 에 리 보 디 는 소스 코드 가 어떻게 실현 되 는 지 보 러 가자. 보고 나 면 우리 스스로 도 바퀴 를 만 들 수 있다.
위의 도입 방법 은
react16.8
버 전 이 고 저 버 전 16.3
은 인용 방법 을 수정 했다.import throttle from 'lodash/throttle';
this.onClick = throttle(this.onClick, 2000);
그러나 이 기능 은 아래로 호 환 되 며, 오래된 방법 은 새 버 전에 서도 사용 할 수 있다.
다음은 새로운 버 전 소스 코드 를 바탕 으로 분석 하 겠 습 니 다.
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
위의 두 줄 은 엄격 한 모델 을 사용한다.
내 보 내기 모듈 을 설정 하 는 방식 (이것 은 잘 모 르 겠 습 니 다. 내 보 내기 방식 을 설정 하고 일부 자 료 를 찾 아 보 았 지만 아직 결과 가 나 오지 않 았 습 니 다. 제 가 알 아 보고 보충 하 겠 습 니 다)
알 겠 습 니 다. 다시 보충 하 겠 습 니 다. 이 소스 코드 가 있 는 파일 은
index.cjs.js
즉, babel 을 통 해 전 환 된 commonJS
코드 입 니 다.모듈 의 출력 대상 추가
__esModule
는 바벨 의 요구 에 부합 하지 않 는 CommonJS 모듈 을 요구 에 부합 하 는 모듈 로 변환 하기 위 한 것 이라는 점 require
에서 드러난다.모듈 을 불 러 온 후에 불 러 온 모듈 이 하나의 __esModule
속성 을 가지 고 있 는 것 을 발견 하면 Babel 은 이 모듈 이 틀림없이 바 뀌 었 다 는 것 을 알 게 될 것 입 니 다. 그러면 Babel 은 불 러 온 모듈 에서 안심 하고 exports.default
이 내 보 낸 대상, 즉 ES6 에 규정된 기본 내 보 내기 대상 을 호출 할 수 있 습 니 다. 그래서 이 모듈 은 CommonJS 기준 에 도 부합 합 니 다.Babel 의 ES6 모듈 화 수요 에 도 부합 합 니 다.그러나 __esModule
이 존재 하지 않 는 다 면 괜 찮 습 니 다. Babel 은 감지 되 지 않 는 __esModule
모듈 을 불 러 왔 을 때 이 모듈 이 CommonJS 기준 에 부합 되 지만 제3자 모듈 일 수 있 습 니 다. Babel 은 이 모듈 을 바 꾼 적 이 없습니다. 나중에 직접 사용 하면 exports.default
오류 가 발생 할 수 있 습 니 다. 그래서 지금 은 default
속성 을 추가 합 니 다.차라리 default
속성 이 자신 을 가리 키 게 하면 좋 겠 다. 그러면 앞으로 실수 하지 않 을 것 이다.이 해석 은 바벨 이 ES6 module 로 전환 하 는 원 리 를 분석 한 데 서 비롯 된 것 으로, 여러 선배 님 들 의 도움 에 도 감 사 드 립 니 다. , , “resize”,“scroll”
/**
* @param {Number} delay
* @param {Boolean} [noTrailing]
* @param {Function} callback
* @param {Boolean} [debounceMode]
* @return {Function} A new, throttled, function.
*/
delay : number 0 , , 100 250( ) 。
[noTrailing] : [] , false, true, ‘delay’ ,
, noTrailing false , ,
( “delay” , )
callback : “delay” ,this ,
“callBack”
[debounceMode]: “debounceMode” true, “delay” “clear” ,
“debounceMode” false, “delay” “callBack” 。
:
function throttle (delay, noTrailing, callback, debounceMode) {
/*
* After wrapper has stopped being called, this timeout ensures that
* `callback` is executed at the proper times in `throttle` and `end`
* debounce modes.
*/
, ,
var timeoutID;
var cancelled = false; //
var lastExec = 0; //
function clearExistingTimeout() {
if (timeoutID) {
clearTimeout(timeoutID);
}
} // exec
function cancel() {
clearExistingTimeout();
cancelled = true;
} // ,
if (typeof noTrailing !== 'boolean') {
debounceMode = callback;
callback = noTrailing;
noTrailing = undefined;
}
// / ,
function wrapper() {
var self = this;
var elapsed = Date.now() - lastExec;
var args = arguments;
if (cancelled) {
return;
} // , lastExec
function exec() {
lastExec = Date.now();
callback.apply(self, args);
}
// true,
function clear() {
timeoutID = undefined;
}
if (debounceMode && !timeoutID) {
// , ,
exec();
}
clearExistingTimeout();
if (debounceMode === undefined && elapsed > delay) {
// , ,
exec();
} else if (noTrailing !== true) {
/*
* , ,
* , ’delay‘ ’clear‘
* false, ’delay‘
*/
timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
}
}
wrapper.cancel = cancel; //
return wrapper;
}
/**
*
* @param {Number} delay
* @param {Boolean} [atBegin]
* @param {Function} callback
* @return {Function} A new, debounced function.
*/
, , ,
delay: , , 100 250( )
atBegin: , false, atBegin false ,
“delay” , atBegin true,
( “delay” , )
callback: 。“this”
“callback”。
function debounce (delay, atBegin, callback) {
return callback === undefined ? throttle(delay, atBegin, false) : throttle(delay, callback, atBegin !== false);
}
exports.throttle = throttle;
exports.debounce = debounce;
본 고 는 제 가 처음으로 진지 하고 꼼꼼 하 게 알 아 본 것 입 니 다. 모든 줄 의 소스 코드 를 연구 하고 자신 이 만 든 바퀴 로 큰 사람 을 비교 하 는 것 입 니 다. 배 워 야 할 것 이 많 습 니 다. 글 에서 해석 이 제대로 되 지 않 고 잘못된 부분 을 설명 하 는 경우 가 많 습 니 다. 선배 님 들 께 서 많이 지적 해 주 셨 으 면 좋 겠 습 니 다.