Typeform / embed

Library to embed Typeforms in your website

Home Page:https://typeform.com/developers/embed/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Android Device] For Widget component, when keyboard shows up, it refreshes entire Typeform Widget

scy0334 opened this issue · comments

[Package Name]
@typeform/embed-react

[Package Version]
2.30.0

[Description]
I built my service on nextjs(13.2.1), react(18.2.0) version.

Widget works perfectly on iPhone, laptop browsers and etc.

But, when I try to answer to a "short sentence", page refreshes automatically on any android devices.

Screen_Recording_20230824-200522_Samsung.Internet.mp4

Hello @scy0334

I think on Android viewport size changes when the keyboard is displayed (in iOS it does not). Are you using any hooks / props / state that might trigger the re-render on viewport resize?

In most cases, if you do unnecessary re-renders it is a performance issue, however not really apparent at first sight. However when your component with embedded typeform re-renders, it is visible right away - the iframe is reloaded.

Please show a reproducible example or relevant components of your react code if you need further help.

Hi @mathio!

There's no hooks/props/state that trigger re-render on viewport resize.

I'll try to make a reproducible example, of which I can share code with you.

Hi @mathio !

I figured out the cause of bug on Android device.

As you've mentioned, I was using useWindowSize hook which listens to "resize" event, triggering re-renders on resize.

So, for the page that uses Typeform embeds, i got rid of the useWindowSize hooks, and now they are working fine.

For the record, is there any other ways I could have written useWindowSize hook without causing to re-render iframe of the Typeform embed?

Here's my reproducible exampe:
https://github.com/scy0334/typeform-embed

Thanks!

What are you using the useWindowSize hook for? I think you will need to change the structure of your app and move the hook into a different component.

Eg. if you have a component like this:

const Page = () => {
  const{ width } = useWindowSize()

  return (
    <div>
      <h1>Width is {width}px</h1>
      <Popover id="x" />
    </div>
  )
}

You could move the logic using the hook into separate component

const Size = () => {
  const{ width } = useWindowSize()

  return <h1>Width is {width}px</h1>
}

const Page = () => {
  return (
    <div>
      <Size />
      <Popover id="x" />
    </div>
  )
}

If you do not need to listen to window resize in you app, you could write a hook that returns initial window size. This will not return new value when the window resizes and will not cause components to re-render:

const useInitialWindowSize = () => {
  const [size, setSize] = useState({});
  useEffect(() => {
    const { innerWidth, innerHeight } = window || {};
    setSize({ innerWidth, innerHeight });
  }, []);
  return size;
};

However it returns only the initial window size, so might not be accurate at all times.

Maybe you only need a hook that returns window width in your app (and updates on resize), but not window height? I think it is height that changes when the keyboard is present.