hash from url gets removed before page loads - javascript

I'm trying to capture hash from url such as this https://examplesite.com/page#time=1/12/2019&index=12344&access_token=JWT but before I get the chance to capture it, the access_token in that url gets removed and upon the site load, I can't capture the hash using window.location.hash
My example is inside a React functional component, using React hooks:
const watchHash = () => {
if (window.location.hash.includes('access_token')) {
console.log(window.location.hash);
}
};
useEffect(() => {
window.addEventListener('hashchange', watchHash);
watchHash();
return window.removeEventListener('hashchange', watchHash);
}, []);
The above code watches the hash and only prints the url that doesn't includes access_token, such as this #time=1/12/2019&index=12344,
event if try to console.log(window.location.hash) outside the hook and at the top of the component itself.
I can't seem to figure out why it's doing this, help appreciated.

Related

NextJs Link causes Error: Loading initial props cancelled

I have nextjs 13 app and I have navbar component with some Nextjs links. After pressing the link and the page starts loading if you click the same link fast some times it throws this error: Error: Loading initial props cancelled.
What I did:
//navbar.ts
const [loadingPath, setLoadingPath] = useState()
useEffect(() => {
Router.events.on('routeChangeComplete', () => setLoadingPath(undefined))
}, [])
const onClickExample= (e) => {
e.preventDefault()
setLoadingPath('/example')
if (loadingPath === '/example' || router.asPath === '/example') return
router.push('/example')
}
//jsx
<Link href="/example" onClick={onClickExample}>Go to Example</Link > // Nextjs Link
There are some discussians like this github issue. It happens on Nextjs 12 too according comments around the net.
This is common user behavior and it's weird to throws such errors.
How do you handle it? Any elegant solution?
I don't see any reason to use onClick in your <Link> here the property href="/example" will make you navigate to /example.
and if you are doing this just to prevent the error then what you are trying to do will not help :
setLoadingPath('/example')
if (loadingPath === '/example')
makes no sens, the loadingPath state will not be updated untill the next render.
This is happening when you try to navigate to another page while the current one is still loading, usually because of a slow connection there are some althernatives like :
const [navigation,setNavigation] = useState('')
//...
const onClickExample = (e) => {
e.preventDefault();
setNavigation("/example"); // when the user clicks you update 'navigation' to the wanted URL to trigger a render
};
//...
useEffect(() => {
if (navigation !== "") { // prevent navigation for the first render
setTimeout(() => {
router.push(navigation); // when the component finishes rendering useEffect runs because navigation is updated then navigate to the wanted URL
}, "500");
}
}, [navigation]);
But you cannot do this with <Link> because it requires href so it will navigate to the given path anyway.
<a onClick={onClickExample}>Go to Example</a>
Try to do it without setTimeout maybe it works for you. In my case it was happening only in development.

Redirecting in react-router-dom v6 in a non-JSX context

I'm trying to redirect a user from the route they are currently looking at to another route programatically. In my case, I am not in a JSX environment, and cannot use any kind of React hooks. How would I go about this?
I tried to use the code block below to redirect (tried using JSX), only to realize that it wouldn't work as it isn't in the context of the root router.
ReactDOM.render(<div>
<Navigate to="/" />
</div>, document.getElementById("redirect"));
I also want to try and redirect without using window.location.href = as that would cause the whole page to refresh, something I don't want to happen.
EDIT: As requested, I am trying to redirect to a page from an event that is emitted by Tauri and is handled by some TypeScript code on the front end. Using window.location.href isn't an issue in any case.
Here is an example of what I'm trying to do:
/**
* Sets up event listeners.
*/
export async function setupListeners() {
console.log("Setting up link event listeners...");
await listen("deeplink", onLinked);
}
/**
* Invoked when a deep link call is received.
* #param event The event.
*/
async function onLinked(event: Event<string>) {
const { payload } = event;
if (payload == "test:")
// redirect("/testPage");
}
See redirect:
import { redirect } from "react-router-dom";
const loader = async () => {
const user = await getUser();
if (!user) {
return redirect("/login");
}
};
(from the docs)

Reflect changes without page refresh

I have created method to delete image as
action.js
export const removeImage = (id, image_id) => async () => {
try {
const response = await axios.delete(
`localhost:3000//api/v1/posts/${id}/delete/${image_id}`,
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
I have call this method in post/[id].js as
<p onClick={() => removeImage(id, imgae.id)}>delete </p>
The problem is when I delete image I should hard refresh page to see changes. How can I solve this.
I have used useEffect hook
useEffect(()=> {
fetchData();
}, [data]);
It worked but load backend server too much.
Another idea I think to use useState hook. but how can I implement in this code?
Thanks in advance
I think that you try to do two different things :
Delete the image on your server with a request
Hide the image from your component / refresh your component src
You need to make the source image property of your component more reactive, like putting it in the state so you can modify it dynamically
Because here, you simply delete the resource on your server but your component is not refreshed or reloaded.
What you shoud do is to hide your component holding the image and display a kind of placeholder after clicking your delete button
Unless your app watches the server for updates you should manually reflect the changes you do on the server in your UI as well. For example, if you have a component, say an ImageButton, that is showing your image, and you remove the image from the server, what is the intended behavior? If you want the image button removed, you can simply set it’s visible property to false.

Router.push or Link not rendering/refreshing the page even thought the url is updated nextjs

I apologize for my horrendous way of explaining my issue. I have shared a link below description which is exactly the same issue I am experiencing. Any kind of help would be greatly appreciated.
I have directory path like pages/request/[reqid].js . When my url is localhost:3000/xyz and I navigate to pages/request/1 by clicking a button on the current page, the page successfully loads the page with proper data from [reqid=1] but when I try to access pages/request/[reqid].js with different reqid (say suppose reqid=2), the url reflects the correct the reqid pages/request/2 but the page remains the same, doesn't change. However if I go back to other pages like localhost:3000/xyz and click a button there to navigate to pages/request/2 it works but from within pages/request/[reqid] it doesn't render a page associated to the corresponding reqid even thought the url is updated. I have tried both Link and router.push ,both fails to render the correct reqid page.
https://github.com/vercel/next.js/issues/26270
It actually failed to include that I was using getServerProps to fetch the data, which was the reason the page wasn't rendering , unless the page was manually refreshed. The page state is not reset for navigation between dynamic routes that served by the same source component.
for example, give page source /a/[param]/index.js, when navigating from /test/123 to /test/124, states on the page wasn't being reset.
So actually happened is the same React Component been rendered with different props. Thus react takes it as a component is rerendering itself, and causing the new navigated page receive stale states.
To fix it, just add {key: } to page initial props or getserversideprops
export const getServerSideProps = async (ctx) => {
try {
const { reqid } = ctx.params;
//fetch code
return {
props: {
key: reqid,
data:data
},
};
} catch (error) {
console.log(error);
}
};

react-native navigation false route params in navigation listener

I am using react native navigation and have two tabs. One of them has a list of entites, the other has a form to submit entities. When ever a new entity is submitted, I'd like to refresh the first tab to be sure, the newest data gets loaded.
I navigate to the first tab like this:
navigation?.navigate('Main', {refresh: true});
This props gets saved as follows:
let {refresh} = route.params;
To check, if the screen needs to refresh, I added a listener in useEffect() like this:
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () =>{
if(refresh){
doRefresh()
}
})
}, [])
Unfortunately, neither "refresh" nor "route.params" directly is ever true inside the listener. Passing the param works, because I took a closer look at the var and it gets true, whenever I submit.
Do I need to access the route.params inside a navigation listener in another way?
Thanks and hit me up, if you need more information on this
The issue is that your useEffect only runs once as your dependencies array [] is empty, and therefore your listener only receives the initial value of refresh.
You need to pass refresh as a dependency to useEffect, and I don't think you even need the focus listener in your case so you would end up with this:
useEffect(() => {
if (refresh) {
doRefresh()
}
}, [refresh])
const onPressCountry = (item,index) => {
navigation.push('SignUp2', {selectedCountryId:item?.countryID, selectedCountryName: item?.name} )
}
use navigation.push instead of navigation.navigate

Categories