[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.