[英]Converting React class component to functional component with hooks : Problem with event listeners
I had a picture zooming component as a React class component.我有一个图片缩放组件作为 React class 组件。 I then wanted to convert it to functional component and make it work with hooks.
然后我想将其转换为功能组件并使其与钩子一起使用。 I almost have it down but I run into this problem that I can only scroll once in and once out.
我几乎把它写下来了,但我遇到了这个问题,我只能滚动一次进出一次。 I'm using state variable size as a limit to zoom, starting at 30. But currently when I scroll it wont continuously keep zooming until limit but just a single step in and out.
我使用 state 可变大小作为缩放的限制,从 30 开始。但是目前当我滚动它时,它不会持续缩放直到限制,而只是一步进出。 What is causing this limit and how can I fix it?
是什么导致了这个限制,我该如何解决?
const ProductPicture = (props) => {
const [size, setSize] = useState(30);
const zoomTarget = useRef(null)
const handleScroll = useCallback((event) => {
if (event.deltaY > 0 && size < 50) {
setSize(size + 2)
} else if (event.deltaY < 0 && size > 20) {
setSize(size - 2)
}
})
useEffect(() => {
zoomTarget.current.addEventListener('wheel', handleScroll, true);
return() => {zoomTarget.current.removeEventListener('wheel', handleScroll, true)}
},[]);
return (
<div className="livetods-product-image-container" style={{
top: openAsModal() ? '25%' : '20%',
left: openAsModal() ? '30%' : '',
right: openAsModal() ? '30%' : '',
width: size + "%"
}} >
<div className="livetods-product-image-button-container" >
<div></div>
<h6 className="livetods-product-image-name">{props.name}</h6>
<span className="livetods-modal-header-close-button" onClick={e => props.hideImage()}>×</span>
</div>
<div style={{width: "100%", height:"100%"}}>
<div ref={zoomTarget} style={{position: "relative"}}>
<div style={{position:'absolute', padding: '5px'}}>
<FontAwesomeIcon icon={faSearchPlus} color={'red'} style={{ width: '20px', height: '20px', pointerEvents:"none"}}/>
</div>
<img src={props.src} style={{borderRadius: "5px", width: '100%'}} />
</div>
</div>
</div>
);
}
You need to pass an updater function to setSize
instead of giving it a value.您需要将更新程序 function 传递给
setSize
而不是给它一个值。 ( Doc ) ( 文档)
const handleScroll = useCallback((event) => {
const deltaY = event.deltaY
setSize((size) => {
if (deltaY > 0 && size < 50) {
return size + 2
} else if (deltaY < 0 && size > 20) {
return size - 2
}
return size
})
}, [])
The useCallback
hook cache the callback so that it will always get the same callback reference as long as no item in the dependency array has changed. useCallback
挂钩缓存回调,以便只要依赖数组中没有任何项目发生更改,它将始终获得相同的回调引用。 (The code in the question misses the dependency array, which is not a valid usage) ( Doc ) (问题中的代码错过了依赖数组,这不是有效的用法)( Doc )
The code in the question always reuse the same callback reference since no dependency array is given.问题中的代码总是重用相同的回调引用,因为没有给出依赖数组。 In this case, inside the callback,
size
is always equals to its initial value (ie 30
) and set the size to either 30 + 2
or 30 - 2
.在这种情况下,在回调内部,
size
始终等于其初始值(即30
)并将大小设置为30 + 2
或30 - 2
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.