Skip to content

<A> not properly triggering nested Suspense #352

@hamoto

Description

@hamoto

Describe the bug

When using A components for navigation to pages which rely on params or location to render, it is not properly triggering nested Suspense fallbacks. It instead waits until the entire page is rendered off screen and only then updates the page content as well as the browser URL path and sets the activeClass accordingly. I understand that the component has built in transitions and that this may be intended behavior, but this causes applications with slow-loading API requests to feel unresponsive.

I've written a very simple example to recreate the issue:

// @refresh reload
import "./app.css";
import {A, Router, Route, cache} from "@solidjs/router";
import {lazy, Suspense} from "solid-js";

export const resource = cache((foo) => {
    return new Promise(resolve => setTimeout(() => resolve({ foo }), 2000))
}, "test")

export default function App() {
    const loadResource = ({params, location}) => {
        void resource(params.foo)
    }

    return (
        <Router root={(props) => {
            return (
                <>
                    <div className={"flex gap-5"}>
                        <A href={"/test1"} activeClass={"underline"}>Test 1</A>
                        <A href={"/test2"} activeClass={"underline"}>Test 2</A>
                        <A href={"/test3"} activeClass={"underline"}>Test 3</A>
                    </div>
                    <Suspense fallback={"Loading..."}>{props.children}</Suspense>
                </>
            )
        }}>
            <Route path={"/*foo"} component={lazy(() => import("~/Test.jsx"))} load={loadResource}></Route>
        </Router>
    );
}

/*
//Contents of Test.jsx

import {createAsync} from "@solidjs/router";
import {resource} from "~/app.jsx";
import {Suspense} from "solid-js";

export default function Test(props) {
    const testResource = createAsync(() => resource(props.params.foo))

    return (
        <Suspense fallback={"Loading 2..."}><pre>{JSON.stringify(testResource())}</pre></Suspense>
    )
}
 */

Steps to Reproduce the Bug or Issue

Start a new solid-start project, paste the above code into app.jsx, create a new file called Test.jsx in /src and paste the commented out "Contents of Test.jsx" there, run the server and click the Test links

Expected behavior

When the link is clicked, the page URL should update immediately, the clicked link should be assigned its active class ("underline" in this example) and the "Loading 2..." Suspense fallback should be triggered, then 2 seconds later it should be replaced with something like {"foo":"test3"}

Screenshots or Videos

unresponsive_links

Platform

  • OS: Windows
  • Browser: Chrome
  • Version: 0.10.8

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions