Do you want to request a feature or report a bug?
Bug
What is the current behavior?
I have a component which listens for resize events (via a BlueprintJS ResizeSensor). When loading a component dynamically with lazy
/ Suspense
, an exception occurs as the resize sensor appears to be unmounted:
Uncaught Error: Unable to find node on an unmounted component.
at invariant (29.chunk.js:86295)
at findCurrentFiberUsingSlowPath (29.chunk.js:90628)
at findCurrentHostFiber (29.chunk.js:90640)
at findHostInstanceWithWarning (29.chunk.js:106349)
at findDOMNode (29.chunk.js:106869)
at ResizeSensor.componentDidUpdate (29.chunk.js:10535)
The resize sensor should be removing listeners on unmount.
Demo: https://codesandbox.io/s/n4241q075l
Related: https://github.com/palantir/blueprint/issues/3141
What is the expected behavior?
No exception is thrown.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Tested with:
Can you test if it works on master?
Nope, it's broken on master, and after bisecting, I confirmed the regression was caused by #14083
EDIT: Something else I found is that before the regression, ResizeSensor.componentDidUpdate
doesn't execute, but now it does.
EDIT 2: Yeah, ReactDOM.findDOMNode
throws when invoked with a suspended component, here's how you can reproduce.
const React = require("react");
const ReactDOM = require("react-dom");
const ReactTestRenderer = require("react-test-renderer");
const { Suspense } = React;
let didSuspend = false;
function Suspend() {
if (!didSuspend)
throw {
then() {
didSuspend = true;
}
};
return null;
}
class Component extends React.Component {
componentDidUpdate() {
ReactDOM.findDOMNode(this);
}
render() {
return null;
}
}
function App() {
return (
<Suspense fallback="Loading">
<Component />
<Suspend />
</Suspense>
);
}
const root = ReactTestRenderer.create(<App />);
root.update(<App />);
This is true both before and after the aforementioned PR, so in any case it looks like it helped us discover this :smile:
EDIT: Something else I found is that before the regression, ResizeSensor.componentDidUpdate doesn't execute, but now it does.
This sounds like a separate problem, can you provide a test case for it?
Here's a minimal repro with ReactDOM:
const Lazy = React.lazy(() => new Promise(resolve => resolve({
default() {
return 'hello';
}
})))
class Child extends React.Component {
componentDidUpdate() {
ReactDOM.findDOMNode(this);
}
render() {
return null;
}
}
class App extends React.Component {
state = {
suspend: false
};
handleClick = () => {
this.setState({ suspend: true });
};
render() {
return (
<React.Suspense fallback="Loading">
<Child />
<button onClick={this.handleClick}>Suspend</button>
<Child />
{this.state.suspend && <Lazy />}
</React.Suspense>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
Okay, so a part of this is covered by https://github.com/facebook/react/pull/14197. It got first broken by #14083 and got fixed in #14164.
However I think repro case in https://github.com/facebook/react/issues/14188#issuecomment-437705392 might be a separate issue. Looking into it.
This sounds like a separate problem, can you provide a test case for it?
Welp, turns out I'm wrong, I actually made a mistake when mocking componentDidUpdate
which resulted in it not being called :stuck_out_tongue_closed_eyes:
Another reproducible example: https://codesandbox.io/s/zwzqp18ool
When does it throw:
This was likely fixed in https://github.com/facebook/react/pull/15312. Can you verify on master?
This was likely fixed in聽#15312. Can you verify on master?
Yes, current master
fixes https://github.com/facebook/react/issues/14188#issuecomment-481252546 for me.
This will get into the next release then.
@gaearon @acdlite,
Seems it still happens. ~I tried to get mini reproduce but it seems happened in complex environment.~
User report reproduce: https://codesandbox.io/s/antd-reproduction-template-sbsiz
Quick click the nav item will throw with Unable to find node on an unmounted component.
ref: https://github.com/ant-design/ant-design/issues/17016
Update:
Create a mini reproduce about this: #15857
Sorry, we didn鈥檛 release the fix yet.
@gaearon any ETA on when this will be available?
We are blocked by this, too (without a pretty significant workaround). Any sense of a release timeframe? @gaearon? Is there some way to find out (in general) when the "next" release is? Sorry if this is covered somewhere..
For the record, this is surfacing for us through Semantic UI React Dropdown. So we're beholden to them as well, but they point us here for the fix. :)
Sorry, we didn鈥檛 release the fix yet.
@gaearon
any new updates?
We've published 0.0.0-db3ae32b8
of all packages, which includes this fix. It is likely to be a release candidate for 16.9.0
. You can give it a try now and see whether it resolves the issue for you. Thanks.
(You should still ask packages to migrate away from findDOMNode
though as it's eventually going to get deprecated.)
We've published
0.0.0-db3ae32b8
of all packages, which includes this fix. It is likely to be a release candidate for16.9.0
. You can give it a try now and see whether it resolves the issue for you. Thanks.
16.9.0 hadn't fix this bug!
We've published
0.0.0-db3ae32b8
of all packages, which includes this fix. It is likely to be a release candidate for16.9.0
. You can give it a try now and see whether it resolves the issue for you. Thanks.16.9.0 hadn't fix this bug!
@MissLlq All reproductions linked in this issue (https://codesandbox.io/s/zwzqp18ool and https://codesandbox.io/s/n4241q075l) no longer crash with 16.9.
If you still encounter this error message with 16.9 please open a new issue.
Most helpful comment
@gaearon any ETA on when this will be available?