question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Draggable components switch between 'controlled' and 'uncontrolled'

See original GitHub issue

The API for draggable components violates react’s controlled vs uncontrolled component paradigm. Any component marked draggable seems to switch between managing its own state and respecting the x, y values that it gets as props.

In my use-case, react-konva is the renderer for a physics-backed layout. When users drag a Rect, there is some elastic feedback, so the Rect shouldn’t be right under the cursor but instead lags behind it by an increasing amount as it is pulled. Since the components switches between the x, y value that it is getting as props (correct, from my physics simulation) and its own x, y state that is is managing since it is draggable, there is a ‘twitching’ effect in the graphics.

Here’s a GIF of the behavior: twitchy-graph

As a much more contrived but direct minimal repro, consider this codePen: https://43momq7017.codesandbox.io/

It should be fairly easy to get the twitching effect I described when you drag the Rect as the components switched between controlled and uncontrolled.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
lavrtoncommented, Dec 24, 2019

I was thinking about this issue. To make a fully controlled component you can do this:

onDragMove={e => {
  const newPos = e.target.position();
  // reset position to its old state
  // so drag is fully controlled by react
  e.target.position({ x: pos.x, y: pos.y });

  // your set state
  setPos({
    x: Math.min(100, newPos.x),
    y: Math.min(100, newPos.y)
  });
}}

The idea is to reset the node position to its original value that we have in the react. And then use new position to set a new state. If you comment setPos the node will be not movable. So it works as a controlled component.

Demo: https://codesandbox.io/s/react-konva-controlled-drag-demo-pxmg8

Probably that little logic in onDragMove can be abstracted into something like react hook.

2reactions
seankimdesigncommented, May 9, 2019

I’ve noticed this issue as well. Dragged elements seems to maintain an internal state outside of the React paradigm. I think react-konva version 1.7.9 and below actually does not have this problem. It must have been introduced short time after.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Draggable Components: A Complete Guide - Copycat
The Complete Guide to React Draggable Components ... What is React Draggable? ... Uncontrolled; What is DraggableCore?
Read more >
react-draggable - npm
Uncontrolled. <Draggable> is a 'batteries-included' component that manages its own state. If you want to completely control the lifecycle of ...
Read more >
Controlled Components and Uncontrolled ... - YouTube
Uncontrolled and Controlled components are terms used to describe React JS HTML form elements.In this tutorial we will build a simple ...
Read more >
Create draggable components with React-Draggable
Explore React-Draggable, a library that simplifies adding dragging movement to React components and elements.
Read more >
Implementing a basic drag functionality in ReactJS
import React, { Component } from 'react'; import './App.css'; class App extends Component { render() { const myStyle = ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found