-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uncaught TypeError: Cannot read property 'dragSource' of undefined #429
Comments
So I'm getting this again, really annoying to debug, this is the stacktrace that I see: So in DragDropContainer, it tries to get the current state: function DragDropContainer(props, context) { // 89
_classCallCheck(this, DragDropContainer); // 90
// 91
_Component.call(this, props, context); // 92
this.handleChange = this.handleChange.bind(this); // 93
this.handleChildRef = this.handleChildRef.bind(this); // 94
// 95
_invariant2['default'](typeof this.context.dragDropManager === 'object', 'Could not find the drag and drop manager in the context of %s. ' + 'Make sure to wrap the top-level component of your app with DragDropContext. ' + 'Read more: http://gaearon.github.io/react-dnd/docs-troubleshooting.html#could-not-find-the-drag-and-drop-manager-in-the-context', displayName, displayName);
// 97
this.manager = this.context.dragDropManager; // 98
this.handlerMonitor = createMonitor(this.manager); // 99
this.handler = createHandler(this.handlerMonitor); // 100
this.disposable = new _disposables.SerialDisposable(); // 101
// 102
this.receiveProps(props); // 103
this.state = this.getCurrentState(); // 104
} In there, it tries to get the next state via connect, however this.handlerConnector is undefined at this point and causes the error can't read dragSource of undefined. DragDropContainer.prototype.getCurrentState = function getCurrentState() { // 173
var nextState = collect(this.handlerConnector, this.handlerMonitor); // 174
if (process.env.NODE_ENV !== 'production') { // 175
_invariant2['default'](_lodashIsPlainObject2['default'](nextState), 'Expected `collect` specified as the second argument to ' + '%s for %s to return a plain object of props to inject. ' + 'Instead, received %s.', containerDisplayName, displayName, nextState);
} // 177
return nextState; // 178
}; |
I've found my root cause this time. My drag source looks like this: export const dragTargets = props => {
return props.item.base.type; // if props.item.base.type is undefined, then you get the error in the title
}; // DragSource.js
if (typeof type !== 'function') {
invariant(
isValidType(type),
'Expected "type" provided as the first argument to DragSource to be ' +
'a string, or a function that returns a string given the current props. ' +
'Instead, received %s. ' +
'Read more: http://gaearon.github.io/react-dnd/docs-drag-source.html',
type
);
getType = () => type;
} If the drag type passed into DragSource is not a function, then it actually does a isValidType check. //decorateHandler.js
receiveProps(props) {
this.handler.receiveProps(props);
this.receiveType(getType(props));
} but I tried following this through (got lost in registerSource.js: So my guess is that if I'm using a function to get the dragType then it doesn't check the type and throws the cryptic error. |
Are you sure that In function validateType(type, allowArray) {
if (allowArray && isArray(type)) {
type.forEach(t => validateType(t, false));
return;
}
invariant(
typeof type === 'string' || typeof type === 'symbol',
allowArray ?
'Type can only be a string, a symbol, or an array of either.' :
'Type can only be a string or a symbol.'
);
} |
When the user provides the DragSource/DropTarget type as a string or array, the type is checked immediately. When the user provides the type as a function, it's not checked until it's added to the registry. If this function returns null (and the type has not yet been set), then the type will never be checked, resulting in cryptic error messages.
It is actually undefined because I was refering to But it never picks up the fact it's undefined, until the call to Actually, I got stuck with registry.addSource, couldn't find any mention of any other |
Hey @mordrax, react-dnd depends on dnd-core. Check out https://github.com/gaearon/dnd-core/blob/master/src/HandlerRegistry.js#L72 I wrote some code that I thought would fix help if the function returned null, but I'll dig in a bit more later :). |
@froatsnook Did you ever dive into this? Otherwise it seems like this might be resolved? I haven't seen other bug reports so I'm inclined to believe it is. |
@froatsnook sorry I didn't see this earlier... I've actually moved my project to Elm and wrote my own drag/drop in much the same way that react dnd does it and have had no problems since. |
That's awesome! Glad that you managed to get a solution working (elm is awesome from what I hear!) I'm going to close this out because it seems as though the issue has been resolved. Thanks for reporting it! |
@kesne 👍 |
Well now I know what I'm using on my next project! |
TL;DR - I've worked out what causes this and fixed it, but I've got no idea how to fix the root cause or protect myself from it happening again.
So I've been scratching my head for the last couple of hours on the error above. The code comes straight out of the textbook:
I first thought it might be my redux smart containers or that the DragDropContext was separated from the DragSource by a few layers of dumb components.
What I ended up finding was that one of the props I was passing into the component wrapped by the drag source was incorrect (bug within my app). Instead of passing in a object, I was passing a integer and then trying to get keys from that integer.
So I thought that there must be some place within ReactDnd that is not wrapping client code (my code) and silently eating up errors.
I've tried wrapping my dropTarget function, the spec functions and all functionality that is linked to ReactDnd but I still get the above error.
The only way that's worked is to fix the bug within my app and that made the error go away.
What really bugs me is that ReactDnd failed silently, and I had no idea why
connect
is undefined.The text was updated successfully, but these errors were encountered: