【发布时间】:2017-11-29 12:59:52
【问题描述】:
我正在使用 React 和 mobx 做一些事情。
我创建了一个 ImageCarousel 组件,在其中显示被点击的图像。 我有一个 previous 和一个 next 按钮(它们本身就是一个组件),用于在图像之间移动。
我尝试使用lodash debounce 包装这些操作(prev 和 next),
但是途中有些事情失败了。
我当前的商店有这些操作:
prevCarouselnextCarouseldebounceAction
debounceAction 只是一个高阶函数,它获取 2 个参数(fn、wait),并使用这些参数调用 lodash debounce。
我的 CarouselButton 组件通过它的道具获得我上面提到的那些动作。在组件内部,我使用onClick 事件触发以通过实际操作(prev 或next)调用debounceAction(fn, wait)。
我不确定如何以正确的方式使用 debounce 来包装我的操作。
我在第二个代码 sn-p(在 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 组件 - 我在这里调用 debounce:
// 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 parent 组件:
// 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>
);
}
}
【问题讨论】:
-
您遇到的故障是什么?是否有控制台错误?
-
@RobertFarley 我没有收到任何错误。我认为我传递给 debounce 的函数不会调用。可能是我写的不对?
-
我不知道 React 和 mobx,但是:lodash 的 debounce 创建(并返回)一个函数,因此 debounceAction() 返回这个函数,并且在 ("HERE I CALL DEBOUNCE !") 行不使用 debounceAction() 的返回值,因此实际上没有人调用该函数。这将称之为:
debounceAction(this.buttonHandler, 400)();- 但你使用 debounce 错误:你可能不会像在你的实现中那样一次又一次地调用 debounce() ;你只需要调用 debounce() 一次,然后一次又一次地调用 debounce() 的 result。 -
return debounce(action(fn), wait)
标签: javascript reactjs lodash mobx debounce