Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injected route param does not trigger template rerender in child component #678

Closed
mathislucka opened this issue Dec 27, 2020 · 10 comments
Closed
Labels
bug Something isn't working has workaround A workaround has been found to deal with the issue help wanted Extra attention is needed

Comments

@mathislucka
Copy link

mathislucka commented Dec 27, 2020

Version

4.0.1

Reproduction link

https://jsfiddle.net/posva/uvzag139/

Steps to reproduce

  • Click on Increment multiple times

What is expected?

Both child components should update their templates.

What is actually happening?

The inner components are not updating at the same time


When using a watch on the injected value, I can see that it actually changes when clicking the router link. It's just the template which is not updating.

@posva
Copy link
Member

posva commented Dec 27, 2020

Hi, thanks for your interest but Github issues are for bug reports and feature requests only. You can ask questions on the forum, the Discord server or StackOverflow.


You are not watching any route param. What you want is maybe use a computed to generate the next link but you can also do

<router-link :to="{ name: 'home', params: { increment: parseInt($route.params.increment) + 1 }}">Increment</router-link>

@posva posva closed this as completed Dec 27, 2020
@posva
Copy link
Member

posva commented Dec 27, 2020

I need to check a bit further, I was confused by the repro

@posva posva reopened this Dec 27, 2020
@mathislucka
Copy link
Author

Yes sorry, I just used the watcher to see if the injected value actually changed. And as it turns out, the value does change but the template doesn't update.

The behaviour is also different for the first and the second child component. When clicking the first component's link once, the second component's template doesn't update. But it will update if you click the link a second time.

I discovered the issue in a more complex project and initially thought it had to do with slots but I could not reproduce that reliably. Also note that when you remove one of the child components everything works as intended.

@posva
Copy link
Member

posva commented Dec 27, 2020

I still have to try to boil it down without vue router because it seems to be a problem with vue.
As a workaround, you can inject the route instead of using a prop:

    const route = useRoute()
    // const { increment } = toRefs(props)
    const increment = computed(() => route.params.increment)

@posva posva added the has workaround A workaround has been found to deal with the issue label Dec 27, 2020
@mathislucka
Copy link
Author

I am using a similar workaround now. I just didn't want to use the route initially because I didn't want to couple the component to the specific route as it is used in other places too.

I also think this is rather an issue with vue but I couldn't reproduce it without using vue router...

@mathislucka
Copy link
Author

I investigated this a bit further but I can't reproduce it without using vue router. When I use the same approach and pass the prop directly to the provider component and then changing the provided value by bubbling up events to the outermost component and changing it there does not produce the same behaviour. I have to use a router link to reproduce it. Hope this helps.

mathislucka added a commit to mathislucka/dualtext that referenced this issue Dec 27, 2020
@mathislucka
Copy link
Author

@posva your workaround carries some issues for me but I'm not sure if it is a bug or intended behaviour. However, it makes it a bit difficult to use the workaround and leads to some complicated and ugly code. When I use the route directly in my component and have the route param as a computed variable the param/computed will update to an undefined when I leave the page via the Browser's back button. All computed variables or watchers depending on that param will be triggered and this can lead to unexpected behaviour because the param is now undefined.

This should illustrate my issue:

const route = useRoute()
const increment = computed(() => route.params.increment)

watch(increment, () => {
  // this will be triggered when leaving the page via the Browser's back button
  // in my case I will make an API call here that depends on the increment param
  // fetch('https://myapi.com/increment/<increment>')
  // this will trigger errors because when leaving the page I'll call fetch('https://myapi.com/increment/undefined')
})

I have updated the repro accordingly. I did not see this issue when using the route params as props. Would be great if the initial problem could be solved.

@posva posva added the bug Something isn't working label Jan 12, 2021
@posva posva added the help wanted Extra attention is needed label Mar 7, 2021
@realityfilter
Copy link

realityfilter commented Mar 9, 2021

I stumbled upon the problem of watched computed router params. They trigger when leaving the route. This seems to be an unintended behavior, right? Should this be a separate issue?

@posva
Copy link
Member

posva commented Apr 2, 2021

This has been fixed in vue core

@posva posva closed this as completed Apr 2, 2021
@BARNZ
Copy link

BARNZ commented Jun 13, 2021

@realityfilter I got tripped up by this today as well.

Simply following the vue-router instructions for data fetching - I was running into the problem of the watcher firing when leaving the route resulting in the data fetching happening twice...

Evans comment here solved this problem once I added the flush: 'post' option. If this was in the above example in the docs it would have saved me a lot of trial and error to get things working as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working has workaround A workaround has been found to deal with the issue help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants