-
Notifications
You must be signed in to change notification settings - Fork 50k
Closed
Labels
Description
React version: 17.0.0-rc.1
Steps To Reproduce
- Create elements out of
lazycomponents, use them conditionally. - Check if the
lazycomponents are dynamically imported.
Link to code example: --
main.jsx:
import React, { lazy, Suspense, useState } from 'react';
import { render } from 'react-dom';
const Checked = lazy(() => import('./Checked'));
const Checked2 = lazy(() => import('./Checked2'));
const Unchecked = lazy(() => import('./Unchecked'));
const Unchecked2 = lazy(() => import('./Unchecked2'));
function App() {
const [checked, setChecked] = useState(false);
const checkedElement = <Checked />;
const uncheckedElement = <Unchecked />;
return (
<>
<label>
<input
type="checkbox"
checked={checked}
onChange={e => setChecked(e.target.checked)}
/>
Toggle me
</label>
<hr />
<Suspense fallback="loading...">
Checked? {checked ? checkedElement : uncheckedElement}
</Suspense>
<hr />
<Suspense fallback="loading...">
Checked? {checked ? <Checked2 /> : <Unchecked2 />}
</Suspense>
</>
);
}
render(<App />, document.getElementById('app'));Checked.jsx:
export default function() {
return 'Checked';
}Checked2.jsx:
export default function() {
return 'Checked 2';
}Unchecked.jsx:
export default function() {
return 'Unchecked';
}Unchecked2.jsx:
export default function() {
return 'Unchecked 2';
}The current behavior
The Checked.jsx chunk is imported eagerly, even though the component isn't immediately rendered.

This doesn't happen in prod mode, or with React 16, or with components that are not createElement-ed eagerly.
This affects react-router, as it uses this pattern:
<Router>
<Suspense fallback={<Loading />}>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/demo">
<Demo />
</Route>
<Route>
<NotFound />
</Route>
</Switch>
</Suspense>
</Router>AFAICT it doesn't break anything, but it is unexpected/confusing.
The expected behavior
lazy components that are not rendered should not be dynamically imported.