Skip to content
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

[Bug]: React. Lazy() combined with Outlet causes extra rendering of parent component #8930

Closed
yibird opened this issue Jun 4, 2022 · 4 comments
Labels

Comments

@yibird
Copy link

yibird commented Jun 4, 2022

What version of React Router are you using?

6

Steps to Reproduce

question: React. Lazy() combined with Outlet causes extra rendering of parent component。
version: 6。
example:

const Parent = () => {
    console.log("render parent")
    return <div>
        <h1>parent</h1>
        <Outlet/>
    </div>
}

const AComponent=React.lazy(()=>import('./demo/A'));
const BComponent=React.lazy(()=>import('./demo/B'));
const CComponent=()=>{
    console.log("render C")
    return <div>C</div>
}
const DComponent=()=>{
    console.log("render D")
    return <div>D</div>
}

export default function App() {
    return <Suspense fallback={<Fallback/>}>
        <BrowserRouter>
            <Link to="/">parent</Link>
            <br/>
            <Link to="/a">a</Link>
            <br/>
            <Link to="/b">b</Link>
            <br/>
            <Link to="/c">c</Link>
            <br/>
            <Link to="/d">d</Link>
            <Routes>
                <Route path="/" element={<Parent/>}>
                    <Route path="/a" element={<AComponent/>}></Route>
                    <Route path="/b" element={<BComponent/>}></Route>
                </Route>
                <Route path="/" element={<Parent/>}>
                    <Route path="/c" element={<CComponent/>}></Route>
                    <Route path="/d" element={<DComponent/>}></Route>
                </Route>
            </Routes>
        </BrowserRouter>
    </Suspense>
}

describe:
If the current access URL is /a or /b, refreshing the browser will print "parent" twice because the component uses React.lazy().
If the current access URL is /c or /d, refreshing the browser will only print "parent" once, because the component is imported normally.

1111

expect: to execute parent only once when React.lazy() is used

Expected Behavior

to execute parent only once when React.lazy() is used

Actual Behavior

If the current access URL is /a or /b, refreshing the browser will print "parent" twice because the component uses React.lazy().
If the current access URL is /c or /d, refreshing the browser will only print "parent" once, because the component is imported normally.

@yibird yibird added the bug label Jun 4, 2022
@timdorr
Copy link
Member

timdorr commented Jun 4, 2022

This is expected behavior. You're wrapping everything in Suspense, which is swapping out the entire tree for your Fallback component while anything underneath it is suspended.

@timdorr timdorr closed this as completed Jun 4, 2022
@yibird
Copy link
Author

yibird commented Jun 5, 2022

I don't think it should be. This will lead to unnecessary rendering. Is there a solution?

@designbyadrian
Copy link

I don't think it should be. This will lead to unnecessary rendering. Is there a solution?

Don't wrap everything in suspense, see this example:

element={
<React.Suspense fallback={<>...</>}>
<About />
</React.Suspense>
}

@woowalker
Copy link

@timdorr but why not rerender again when page not refresh but switch to b from a ? b is also lazy component

brophdawg11 pushed a commit that referenced this issue Mar 27, 2024
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants