Telegram-Mini-Apps / telegram-apps

Made from scratch TypeScript packages, examples and documentation you will surely need to start developing on Telegram Mini Apps.
https://docs.telegram-mini-apps.com/
MIT License
514 stars 117 forks source link

[Bug]: useViewport and useViewportRaw do not work in latest version when using `next dev` #310

Closed iuriiiurevich closed 3 months ago

iuriiiurevich commented 3 months ago

Telegram Application

Telegram for iOS, Telegram for macOS

Describe the Bug

When using next dev --experimental-https, useViewport returns undefined, and useViewportRaw returns empty object.

"@tma.js/sdk": "^2.0.1",
"@tma.js/sdk-react": "^2.1.1",

initViewport works as expected. When using next buildnext start, useViewport and useViewportRaw also work as expected.

To Reproduce

import { useViewport, useViewportRaw } from '@tma.js/sdk-react';

const viewport = useViewport();
const viewportRaw = useViewportRaw();

console.log({ viewport, viewportRaw });
yarn dev

Expected Behavior

useViewport and useViewportRaw work as expected in both development and production mode 🙃

heyqbnk commented 3 months ago

Hey! Could you please check out the Nextjs template _app.tsx file? useViewport may return undefined in case, the component is initializing.

Also, remove the @tma.js/sdk dependency and update @tma.js/sdk-react. Fixed this problem not really long time ago.

I will add docs related to this topic soon, sorry.

iuriiiurevich commented 3 months ago

@heyqbnk

useViewport may return undefined in case, the component is initializing.

Yes, that's right, and then it should return a value, but in development mode it always returns undefined. Sorry for the ambiguity.

Updated @tma.js/sdk-react to version 2.1.2, the issue is still there.

heyqbnk commented 3 months ago

I can't reproduce it in the template. Could you try this code?

import { useViewport, useViewportRaw } from '@tma.js/sdk-react';

function Component() {
  const viewport = useViewport({ 
    ssr: {
      state: {
        isExpanded: false,
        height: 100,
        width: 100,
        stableHeight: 100,
      }
    }
  });

  useEffect(() => {
    console.log({ viewport });
  }, []);

  return null;
}
iuriiiurevich commented 3 months ago

Could you try this code?

Yep, that code works ok. It turns out that my original reproduction code didn't actually have this issue, sorry again for misleading.

But the following code actually doesn't work (always returns undefined):

"use client";

import { useEffect, useState } from "react";
import { useViewport, isTMA } from "@tma.js/sdk-react";

function TmaInitializer() {
  const viewport = useViewport();

  console.log({ viewport });
}

export function Component() {
  const [isTma, setIsTma] = useState();

  useEffect(() => {
    isTMA().then(setIsTma);
  }, []);

  return isTma && <TmaInitializer />;
}
heyqbnk commented 3 months ago

Seems strange. Could you provide a reproducible repo so i could clone it and check the error?

iuriiiurevich commented 3 months ago

Of course, here it is: https://github.com/iuriiiurevich/nextjs-tmajs-useviewport-undefined

heyqbnk commented 3 months ago

Yeah, I can reproduce the problem, but only in case, the condition return isTma && <TmaInitializer />; is specified. Don't really get what is wrong. Will take a look a bit closer after releasing an update today. Thank you for report

heyqbnk commented 3 months ago

I have found out what the problem is. The reason is the React's brilliant StrictMode improperly working with refs, we are using in sdk-react. To be solved soon.

heyqbnk commented 3 months ago

Released in #319. Let me know if something is still wrong.

heyqbnk commented 3 months ago

Hey @iuriiiurevich. This functionality was slightly changed. Check out new docs: https://docs.telegram-mini-apps.com/packages/tma-js-sdk-react