'window.addEventListener('load',... not firing on Safari?
I need redirect page after it load and get param from URL. I can do by button click.
But I want redirect page automatic (without user input). I am use window.addEventListener('load', () => handleClick())
and it work well on Chrome. But on Safari (desktop and mobile) it not always fire (only sometimes it fire - not always).
I can see this by add alert('Beginning');
in handler - on Chrome this fire automatic after page load, but not on Safari.
How I can solve this?
Thanks!
const handleClick = async (event) => {
alert('Beginning'); //For debugging
const stripe = await stripePromise;
const { error } = await stripe.redirectToCheckout({
param,
});
}
if (typeof window !== `undefined`) {
const param = new URLSearchParams(window.location.search).get('param');
}
const Page = () => {
if (typeof window !== `undefined`) {
window.addEventListener('load', () => handleClick())
}
return (
<section >
<button role="link" onClick={handleClick}> //Only for fallback
Press
</button>
</section>
);
};
export default Page;
Solution 1:[1]
The load
event probably wouldn't be very reliable, since your component probably wouldn't be mounted until after the DOM is loaded. Instead, you can use the lifecycle methods of React component to respond when your component is mounted to the page. For example:
function Component() {
useEffect(() => alert(1), []);
return (
<h1>hello world!</h1>
);
}
You can find more information about the Effect hook in the documentation. Using it with an empty array makes it work like componentDidMount()
for class components.
Solution 2:[2]
if you want to fire a function just in loading page and redirect it to another url you can use auto call function like this
(function(){
alert('Beginning');
if (typeof window !== 'undefined') {
const param = new URLSearchParams(window.location.search).get('param');
}
if (param !== 'undefined' && param !== null $$ param!==[]){
window.location.href = 'your_new_url_string?param='+param;
}
})();
Solution 3:[3]
I strongly advise that you avoid referencing the DOM directly using listeners such as window.addEventListener
or document.addEventListener
. In fact, this is why you are using React and not jQuery, to create a virtual DOM instead of charging the real DOM directly and reducing the web performance.
In React, you have React hooks to achieve what you are trying to do. They expose a bunch of lifecycle methods that trigger some events. In your case, useEffect
fits your requirements. This hook is similar to componentDidMount()
and componentDidUpdate()
:
By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.
Due to the needs of Strapi payments and Safari mobile (needs to wait for the page load) I've mixed the hook and your approach to ensure that the effect is triggered when the page is loaded.
Applied to your code:
const Page = () => {
useEffect(() => {
window.addEventListener('load', () => handleClick())
}, []);
return (
<section >
<button role="link" onClick={handleClick}> //Only for fallback
Press
</button>
</section>
);
};
export default Page;
Basically, the code will trigger the useEffect
function once the DOM tree is loaded and it will execute your handleClick
function. The empty array ([]
) passed as an argument is called deps
; means that you are triggering the effect only once. Of course, it will work in all browsers since it's a React feature.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | timtim17 |
Solution 2 | Sobhan Zarinpour |
Solution 3 |