React可拖动Resize组件左侧拖拽后复位问题求助
解决方案
问题根源
你遇到的左侧拖拽后div恢复初始位置的问题,核心原因是使用useState存储初始尺寸和位置时,React的state更新是异步的——拖拽开始时设置的initialSize不会立刻生效,导致拖拽过程中计算宽度时依赖的是旧的state值,最终松开后无法保留调整后的宽度。
修改后的代码
import { useRef } from 'react'; import PostViewer from '../PostViewer/PostViewer'; import './ContainerResize.scss' import * as htmlToImage from 'html-to-image'; import download from 'downloadjs' function savePng() { htmlToImage.toPng(document.getElementById('Resizable')) .then(function (dataUrl) { download(dataUrl, 'tweet.png'); }); } const ContainerResize = (props) => { // 改用useRef存储初始值,避免异步更新问题 const initialPosRef = useRef(null); const initialSizeRef = useRef(null); const resizable = useRef(null); const initial = (e) => { initialPosRef.current = e.clientX; initialSizeRef.current = resizable.current.offsetWidth; console.log(resizable.current.offsetWidth) } const resizeLeft = (e) => { const newWidth = initialSizeRef.current + (initialPosRef.current - e.clientX); resizable.current.style.width = `${newWidth}px`; } const resizeRight = (e) => { const newWidth = initialSizeRef.current + (e.clientX - initialPosRef.current); resizable.current.style.width = `${newWidth}px`; } return ( <div className="containerResize"> <button onClick={savePng}>Save</button> {/* 修正重复的id,改为唯一标识 */} <div id="DraggableLeft" draggable="true" onDragStart={initial} onDrag={resizeLeft} /> <div id="Resizable" ref={resizable}> <PostViewer tweetParam={props.tweetParam} /> </div> <div id="DraggableRight" draggable="true" onDragStart={initial} onDrag={resizeRight} /> </div> ); } export default ContainerResize;
关键修改点
- 替换为useRef存储初始值:
useRef的更新是同步的,能准确记录拖拽开始时的实时位置和尺寸,避免state异步更新导致的计算偏差。 - 修正重复DOM id:原代码中两个拖拽元素id都是
Draggable,属于DOM id冲突问题,改为DraggableLeft和DraggableRight保证唯一性。 - 简化宽度计算逻辑:直接使用ref的当前值进行计算,确保拖拽过程中宽度计算的准确性,松开后能保留最终调整的尺寸。
内容的提问来源于stack exchange,提问作者Hayato175
相关产品推荐
相关产品推荐

