react-grid-layout / react-grid-layout/react-draggable
Draggable shifts position after reload of page (persistent coordinates)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 9.3k
- Forks
- 1k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 4
Description
Hi,
I am developing an application where users can create views consisting of draggable components. As i want the views to be persistent i store the x/y-coordinates of each component in a database. When a page (view) is rendered, i then fetch the coordinates and use these to populate the view (using the defaultPosition-prop)
This works great but i have an infuriating problem. The first time a view is refreshed after a new component is added to a view (and saved), the components will shift position down and to the right. I made a short video showcasing the problem:
https://streamable.com/h00fm8
As can be seen in the console - the coordinates used when rendering the view after the reload are identical to the ones that are saved, but for some reason the element moves!
Here is my draggable component:
return (
<Draggable
grid={[25, 25]} disabled={!props.editingEnabled} defaultPosition={{x: x, y: y}} onStop={handleStop}>
<div style={{position: "static"}} //have tried with absolute and fixed as well, didn't help
<h1>Testing</h1>
</div>
</Draggable>
)
handleStop:
const handleStop = (event) => {
let x = event.layerX;
let y = event.layerY;
console.log("Saving position of element");
console.log("Saving X/Y-position " + x + ", " + y);
setX(x);
setY(y);
props.handleMoveCallback(x, y, props.componentName)
};
handleMoveCallback is in the parent of the element:
handleMoveCallback = (x, y, componentName) => {
this.updateComponent(x, y, componentName);
};
updateComponent = (x, y, componentName) => {
let existingPositions = this.state.componentPositions;
if (existingCompNames.includes(componentName)) {
let objIndex = existingPositions.findIndex((ep => ep.componentName === componentName));
existingPositions[objIndex].x = x;
existingPositions[objIndex].y = y;
this.setState(
{ componentPositions: existingPositions }, this.saveView());
}
};
saveView just posts the array of component positions to the backing API where it's stored in the database.
The components are then rendered inside of an absolute position div:
....
let components = this.state.componentPositions.map((c) =>
<DraggableFunctionComponent id={c.componentName} key={c.componentName}
x={c.x} y={c.y}
componentName={c.componentName} parentCallBack={this.handleMoveCallback}
/>
.....
<div style={{ position: "absolute" }}>
{components}
</div>
Any help would be greatly appreciated
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reload behavior around the Draggable component using defaultPosition, then trace the coordinates through handleStop, updateComponent, saveView, and the parent render. Compare the persisted values with the position applied after reload; done means components retain their saved coordinates after refreshing the page.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100