tauri icon indicating copy to clipboard operation
tauri copied to clipboard

[bug] Can't use suspense with Next.js and SWR

Open boul2gom opened this issue 2 years ago • 0 comments

Describe the bug

When i go on my page, the website waits for release be fetched instead of displaying skeleton with suspense. I try multiple ways, but with tauri it seems to be impossible to use React suspense.

This is my utils.ts code :

export function invoke_backend(caller: string, command: string, args?: InvokeArgs, callback?: (result: any) => void, error?: (error: any) => void) {
    invoke(command, args)
        .then((result) => callback && callback(result))
        .catch((exception) => {
            error && error(exception);
            throw new Error('[' + caller + '] Error: ' + exception);
        });
}

export async function fetch_backend<T>(caller: string, command: string, args?: InvokeArgs): Promise<T> {
    return new Promise((resolve, reject) => {
        invoke_backend(caller, command, args, (result) => resolve(result), (error) => reject(error));
    });
}

This is my Logo.tsx :

const LogoSkeleton = () => {
    return (
        <Code fw={700} className={classes.release_block}>...</Code>
    );
}

export default function Logo() {
    const { data } = useSWR("latest_release", () => fetch_backend<string>("Logo", "fetch_release"));

    return (
        <>
            <Group justify="space-between" className={classes.logo}>
                <Image src={"paperless-ngx.png"} alt={"Paperless Logo"} width={159} height={60}/>
                <Suspense fallback={<LogoSkeleton />}>
                    <Code fw={700} className={classes.release_block}>{data}</Code>
                </Suspense>
            </Group>
        </>
    )
}

This is my page.tsx :

const Logo = dynamic(() => import('@/src/components/Layout/Navigation/Logo'), {
  suspense: true,
  ssr: false,
})

export default function Page() {
  return (
      <SWRConfig value={{ suspense: true }}>
        <div className={classes.navigation_container}>
          <Logo />
        </div>
    </SWRConfig>

And lastly, this is my system.rs :

#[tauri::command(async)]
pub async fn fetch_latest_release(
    client: State<'_, reqwest::Client>,
    cache: State<'_, Arc<MemoryCache>>,
    client: tauri::State<'_, Arc<reqwest::Client>>,
) -> Result<String, String> {
    const URL: &str = "https://api.github.com/repos/boul2gom/paperless-rs/releases/latest";
    const ERROR: &str = "Error while fetching the latest release";

    let resp = client.get(url).send().await?;
    let json = resp.json().await?;

    let tag_name = value["tag_name"].as_str().ok_or_else(|| "No tag_name in the response".to_string())?;
    let version = tag_name.trim_start_matches('v');

    Ok(version)
}

Reproduction

The code is above, file per file, and the same issue happens also when calling backend through useEffect (to get window defined)

Expected behavior

Suspense should display skeleton until data is fetched, and only when its done display the release

Full tauri info output

[✔] Environment
    - OS: Windows 10.0.22621 X64
    ✔ WebView2: 121.0.2277.128
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.75.0 (82e1608df 2023-12-21)
    ✔ cargo: 1.75.0 (1d8b05cdd 2023-11-20)
    ✔ rustup: 1.26.0 (5af9b9484 2023-04-05)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 21.6.1
    - pnpm: 8.15.1

[-] Packages
    - tauri [RUST]: 1.5.4
    - tauri-build [RUST]: 1.5.1
    - wry [RUST]: 0.24.7
    - tao [RUST]: 0.16.5
    - @tauri-apps/api [NPM]: 1.5.3
    - @tauri-apps/cli [NPM]: 1.5.9

[-] App
    - build-type: bundle
    - CSP: unset
    - distDir: ../out
    - devPath: http://localhost:25565/
    - framework: React (Next.js)
    - bundler: Webpack

Stack trace

No response

Additional context

No response

boul2gom avatar Feb 19 '24 14:02 boul2gom