Comments (17)
@gaearon I'm having almost the same issue as this one. I have a simple sortable list that gets controlled by Redux. The sorting of the list is done almost the same way as this example.
Except the problem is, items can get removed from that list. The state gets updated with a complete new list retrieved from the store with less items. The unmount of the items happens and the dragEnd is not triggered.
The problem only occurs when a new list is presented with an item missing
from react-dnd.
I'll need some time to think on that, will look later in the evening.
from react-dnd.
Pardon for dragging my feet on this. I'm a bit busy with work stuff at the moment.
Is this urgent?
from react-dnd.
No problems, not urgent at all. I'm already the hacky way I mentioned, it works for my usecase.
from react-dnd.
OK, let me know if you have other ideas for fixing this as well.
I'll try to find some time next week to look into this!
from react-dnd.
Here is the a brain dump:
I see two different things here.
1- When source component is unmounted during drag, the endDrag
defined on source component becomes irrelevant. Removing the source component may not be a common case, but for trello like functionality, I couldn't come up with any other solutions (Moving an item from one container to other). I thought about not removing, but hiding the source item while dragging, but couldn't find a reliable way of doing it.
While the action looks like moving an item, I'm essentially removing the item in one container, and adding a new one with same properties in another container. I also thought about if I can somehow carry the source item to another component without unmounting it, but haven't tried it, and don't know if it's even possible or feasible.
2- Assuming unmounting the source component during drag is the only way, I need to run a function when drag finishes. I'm achieving that by subscribing the DragDropStore
of react-dnd in the parent component, and reacting to changes there. There isn't any way to get dragged item from the DRAG_END
event, thus I added the lastDraggedItem
stuff.
If there is way to solve 1 (endDrag
defined on source item not working if it's unmounted while dragging), 2 becomes irrelevant (at least for this usecase).
This isn't a big problem for me, as subscribing to the DragDropStore
is trivial.
On further thought, if unmounting the component while dragging is common enough usecase, may be we can offer some alternative syntactic sugar to define beginDrag
& endDrag
on parent component, and passing to child via props, and using them in DragDropMixin
on child component.
I'm not sure if this is feasible or worth the effort either.
I'll give it some more thought.
from react-dnd.
I thought about not removing, but hiding the source item while dragging, but couldn't find a reliable way of doing it.
render() {
var { isDragging } = this.getDragState(ItemTypes.CARD);
if (isDragging) {
return null;
}
...
}
?
from react-dnd.
I'm sorry, I should have been more clear on that. The problem is not with hiding, but the application logic becomes becomes complicated with hiding, breaking the one way data flow.
On my usecase with trello-like app, when card is moved over to another list while dragging, I just fire an action to stores, removing it from one list and adding to another. React + Flux takes care of the rest.
There was all sorts of different usecases that my users came up with, user can drag card to another list first, than moving to original position without dropping, and than moving again etc. It's doable with hiding it, but becomes a lot more complicated than just handling it React + Flux.
Here is a short video of it in action: https://www.dropbox.com/s/852c0dyribbtykf/react-dnd-is-awesome.mov?dl=0
I'll think about it more tho.
Thanks.
from react-dnd.
Your example makes total sense.
I think we should fire endDrag
ourselves if component is removed.
Why does this line not help us?
https://github.com/gaearon/react-dnd/blob/master/modules/utils/NativeDragDropSupport.js#L99
from react-dnd.
@nelix had a similar problem while implementing the mousemove backend (#53).
He tried to make a trello-like example and noticed that, once card is moved into another column, it no longer “knows” it's the one that is being dragged.
Here's the workaround I proposed in Gitter chat:
- Add
key
property todragSource
protocol (let's think later if we want to make it a breaking change, warn when it's missing, or use something like_nextId++
by default). It needs to be a string. Thekey
uniquely identifies drag source in component tree, so even if component is removed and added in some other part of component tree, we can still recognize it as the current drag source. - When drag begins, put that
dragSource.key
asdraggedItemKey
along withdraggedItemType
in action (and thus in Store). Read it from store ingetStateFromDragDropStore
so it gets intostate
. - Change
createDragDropMixin#getDragState
to comparethis._dragSources[type].key === this.state.draggedItemKey
instead of looking atownDraggedItemType
. - When component mounts, if we're in the middle of a drag and its type and key match
draggedItemType
anddraggedItemKey
, we need to establish it as “resurfaced” component instance for this particular drag source. We may want the backend to change its component reference to it. We need to ensure all events that were firing on previous component instance, now fire on this one.
To reiterate, I suggest that drag source can “jump onto” another component if that component has same _dragSources[type].key
and original component is dead. We should probably fail hard if there are two components mounted at the same time with the same key
(not sure).
I think this should also solve your issue. In your case, the card in another column will receive endDrag
, although physically it's a different component.
from react-dnd.
Okay, I think I figured it out.
We will follow react-router's lead and make configureDragDrop
static. Each method will accept component
as first argument.
If drag source is unmounted while dragging, we will call endDrag
with a null component
argument.
from react-dnd.
Changes to the api to make it static are here #56
from react-dnd.
Fixed in 0.7.0.
@hakanderyal Can you give it a go?
from react-dnd.
I'm sorry that I couldn't join you guys, crunch time at work for the past week.
I'm hoping to try the new stuff and help wherever I can in a few days.
from react-dnd.
No problem. Thanks for bringing this to our attention :-)
from react-dnd.
Your example makes total sense.
I think we should fireendDrag
ourselves if component is removed.Why does this line not help us?
https://github.com/gaearon/react-dnd/blob/master/modules/utils/NativeDragDropSupport.js#L99
how can we fire endDrag ourselves?
from react-dnd.
Maybe this can help.
from react-dnd.
Related Issues (20)
- please keyboard functionality
- Preview Image only works once, on the first drag. HOT 3
- Uncaught Invariant Violation: Expected an existing source.
- Library breaks textareas, inputs etc. HOT 1
- table 拖拽时 使用最新版本的React-dnd Api时 出现node.addEventListener is not a function
- 拖动时useDrag无法访问组件内的变量 HOT 1
- @react-dnd/asap trigger swc error `env` and `jsc.target` cannot be used together
- Custom Drag Layer elements don't update until AFTER I drag it. HOT 1
- Redux v5
- Where is dropEffect coming from?
- Hello! I am kupraa from Indonesia, I am very excited to join the project and the communitystar_struck. Wish the project success and strong developmentheart
- [Question] Working with DnD and PrimeReact's DataTable HOT 1
- Will there be a new version released ? and when will the next version be released? HOT 1
- Missing license for some inner packages
- Unable to drag list item after removing/unchecking particular items. Need help.
- Cannot write a unit test to make sure that it is not possible to drag some draggable HOT 1
- Adding accessibility features to the library
- Jest encountered an unexpected token HOT 2
- Styling not working in the beginning of the tutorial chessboard.
- run demo online throw error
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-dnd.