gpt4 book ai didi

javascript - 为什么 debounce 不调用我的函数?

转载 作者:行者123 更新时间:2023-12-03 02:57:30 26 4
gpt4 key购买 nike

我正在使用 Reactmobx 开发一些东西。

我创建了一个 ImageCarousel 组件,在其中显示单击的图像。我有一个上一个和一个下一个按钮(它们本身就是一个组件),用于在图像之间移动。

我尝试用 lodash debounce 包装这些操作(上一个下一个),但途中出现了一些问题。

我当前的商店有这些操作:

  • 上一页轮播
  • nextCarousel
  • debounceAction

debounceAction 只是一个高阶函数,它获取 2 个参数(fn、wait),并使用这些参数调用 lodash debounce

我的 CarouselButton 组件通过其 props 实现我上面提到的那些操作。在组件内部,我使用 onClick 事件触发,以使用实际操作(prevnext)。

我不确定如何以正确的方式用去抖来包装我的 Action 。

我在第二个代码片段(在CarouselButton 组件中)中调用debounceAction(包装去抖的HOF)。

你看到我的错误了吗?

galleryStore.jsx - 当前商店:

class GalleryStore {

// Observables
@observable images = [
// ....images
];

@observable carouselleButtons= {
next: "fa fa-chevron-right",
back: "fa fa-chevron-left"
}
@observable selectedImageIndex = null;
@observable hideCarousel = true;
@observable onTransition = false;

// Actions
selectImage = (index) =>{
this.selectedImageIndex = index;
}

toggleCarousel = () =>{
this.hideCarousel = !this.hideCarousel;
}

carouselNext = () => {
if(this.selectedImageIndex == this.images.length - 1) {
return;
}

this.onTransition = true;
setTimeout(() => {
this.selectedImageIndex = this.selectedImageIndex + 1;
this.onTransition = false;
},500)
}

carouselPrev = () => {
if(this.selectedImageIndex == 0) {
console.log('start of the collection');
return;
}

this.onTransition = true;
setTimeout(() => {
this.selectedImageIndex = this.selectedImageIndex - 1;
this.onTransition = false;
}, 500)
}

debounceAction = (fn, wait) => {
//lodash's debounce
return debounce(fn, wait);
}

carouselButton 组件 - 此处我调用去抖动:

// React's
import React from 'react';

// Styles
import CarouselButtonStyle from './carouselButtonStyle';

// CarouselButton Component
export default class CarouselButton extends React.Component {
debounce = (e) =>{
const { debounceAction } = this.props;

// -----> HERE I CALL DEBOUNCE ! <---------
e.stopPropagation();
debounceAction(this.buttonHandler, 400);
}

buttonHandler = (e) => {
const {limit, index, action, debounceAction} = this.props;

if(index == limit) return;
else action();
}

render(){
const {limit, index, icon, action, debounceAction} = this.props;

return(
<CarouselButtonStyle
onClick={(e) => {this.debounce(e)}}
className={ index == limit ? 'end-of-collection' : '' } >

<i className={icon} aria-hidden="true" />
</CarouselButtonStyle>
);
}
}

imageCarousel.jsx - carouselButton 组件:

// React's
import React from 'react';

// Mobx-react's
import { observer, inject } from 'mobx-react';

// Styles
import ImageCarouselStyle from './imageCarouselStyle';

// Components
import ImgContainer from './imgContainer/imgContainer';
import CarouselButton from './carouselButton/carouselButton';

// ImageCarousel Component
@inject('galleryStore')
@observer
export default class ImageCarousel extends React.Component {
closeCarousel = () => {
this.props.galleryStore.toggleCarousel();
}

onKeyDown = (e) => {
const { keyCode } = e;

if(keyCode ===27) this.onEscHandler();
else if (keyCode == 37) this.onLeftArrow();
else if (keyCode == 39) this.onRightArrow();
else return;
}

onLeftArrow = () => { this.props.galleryStore.carouselPrev() }

onRightArrow = () => { this.props.galleryStore.carouselNext() }

onEscHandler = () => { this.closeCarousel() }

componentDidMount(){
document.addEventListener('keydown', this.onKeyDown, false);
}

render(){
return(
<ImageCarouselStyle
hidden={this.props.galleryStore.hideCarousel}
onClick={this.closeCarousel} >

<CarouselButton action={'prev'}
icon={this.props.galleryStore.carouselleButtons.back}
action={this.props.galleryStore.carouselPrev}
limit={0}
index={this.props.galleryStore.selectedImageIndex}
debounceAction={this.props.galleryStore.debounceAction} />

<ImgContainer
images={this.props.galleryStore.images}
imgIndex={this.props.galleryStore.selectedImageIndex}
onTransition={this.props.galleryStore.onTransition}/>

<CarouselButton action={'next'}
icon={this.props.galleryStore.carouselleButtons.next}
action={this.props.galleryStore.carouselNext}
limit={this.props.galleryStore.amountOfImages}
index={this.props.galleryStore.selectedImageIndex}
debounceAction={this.props.galleryStore.debounceAction} />

</ImageCarouselStyle>
);
}
}

最佳答案

问题是您必须从 CarouselButtondebounce 方法返回 debounceAction

debounce = (e) =>{
const { debounceAction } = this.props;

// -----> HERE I CALL DEBOUNCE ! <---------
e.stopPropagation();
debounceAction(this.buttonHandler, 400);
// -^^^ must return here
}

但是,我建议更进一步,以避免将来出现困惑。只需在需要时调用 lodash 的 debounce,而不是在代码中多次重写它并导致有问题的方法名称。

以下是如何包装点击处理程序的最基本示例:

class Button extends React.Component {
handleClick = _.debounce((e) => {
alert('debounced click reaction')
}, 1000)

render() {
return <button onClick={this.handleClick}>CLICK ME</button>
}
}

ReactDOM.render(
<Button />,
document.getElementById('app')
);
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

关于javascript - 为什么 debounce 不调用我的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47553486/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com