-
Notifications
You must be signed in to change notification settings - Fork 469
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
Simplify usePage()
hook in Vue 3 adapter
#1373
Conversation
4ec3e0f
to
d02f13d
Compare
@reinink I think this may have some problems, since we are returning only the value at the moment of executing the composable usePage, we lose the possibility of having computeds/watchers that react to changes in the data provided by usePage. Anyway, this is just a warning since I don't know how the navigation between components works in Inertia and if the data is refreshed by reloading all the data and not mutating the ref this would not be a problem. Here a simple demo (only recreating the problem, without Inertia) demo Thanks for your work, Inertia is great! |
In 99.9% of the cases this would be fine. On the other hand, I think you can simply do: And the use case to watch page is extremely rare I think. |
@JoseLuisRNP So from my testing, making the I've tested this new implementation with Inertia's persistent layout in Vue 3 (see here), and it updated exactly as expected when navigating between pages. That was my main concern as well, but it seems to work perfectly. That said, I am hoping to get another 1.0 beta out this week, so hopefully folks can battle test this change for me, just in case I missed anything. |
The problem with your test is that you're using the Inertia v0 basic usage const page = usePage()
const pageTitle = computed(() => page.props.value.title)
// This is reactive because we are dereferencing the computed's value within another computed, no problem here Inertia v1 const page = usePage()
const pageTitle = computed(() => page.props.title)
// This is not reactive because the computed page has already been unrefed
const pageTitle = computed(() => usePage().props.title)
// This is reactive because the usePage method is unrefing a computed, basically doing page.value.props.title
// but it goes against vue's mixin best practices Inertia v0 with vue`s best practices const page = reactive(usePage().props)
// Notice how we don't need to use `.value` thanks to `reactive`
const pageTitle = computed(() => props.title);
// This is still reactive because vue makes everything accessed within reactive another reactive proxy
// Even better make it your own composable
import {reactive} from 'vue';
import {usePage} from '@inertia/vue3'
export usePageProps = () => reactive(usePage().props)
// PROPS IS REACTIVE, WE DON'T EVEN NEED COMPUTED PROPERTIES!!! START THE REVOLUTION 🎊
const props = usePageProps()
According to vue's guidelines, this PR solves a non existent problem and effectively creates reactivity problems for components that don't remount when swapping component
This is very probably why But what you could do is make the page Or revert the change and wrap the return value in reactive export function usePage() {
return reactive({
props: computed(() => page.value.props),
url: computed(() => page.value.url),
component: computed(() => page.value.component),
version: computed(() => page.value.version),
})
} This removes the need from |
I had the same issue when I used |
Is there any chance this is getting reverted? |
I also had a lot of issues with that, so I've submitted a fix. |
For reference on composable best practices https://vuejs.org/guide/reusability/composables.html#conventions-and-best-practices I really think such a breaking change should have had a bit more thoughts before a release to v1, and reviews in hindsights. Given there where people already warning about this during the beta (and no 4 days of beta for a breaking change to go directly to release is not enough). No huge deal though it can be fixed without another breaking change by reverting and using Overall, there is a global disregard for feedback in inertia and most changes are unilateral and PR's and issues from outside the inertia team left unreviewed, which I think is a big problem with this project, some issues which are reported straight after a poorly tested release never even get a reply and most of them provide a PR which also goes unreviewed, and some other issues get immediate attention in a random manner. There was also recently a force push to master which left a bitter taste @reinink How are those releases reviewed and tested, how are breaking changes decided (I really hope it's not just with the amount of thumbs up in a PR)? How are issues prioritized? Do you need more maintainers to help review issues and classify bugs in inertia? Do you have briefings or a process in place? Who has permission to do what? Because I'm not happy with the state of this project and I'd like to help, but I need to know if and how |
For those who would like to fix this behaviour while waiting for #1469 to be merged, you can do: import { Page, PageProps } from '@inertiajs/core'
import { usePage as buggyUsePage } from '@inertiajs/vue3'
import { computed, reactive } from 'vue'
/** @see https://github.com/inertiajs/inertia/pull/1469 */
const usePage = <SharedProps extends PageProps>(): Page<SharedProps> => (
reactive({
props: computed(() => buggyUsePage<SharedProps>().props),
url: computed(() => buggyUsePage<SharedProps>().url),
component: computed(() => buggyUsePage<SharedProps>().component),
version: computed(() => buggyUsePage<SharedProps>().version),
scrollRegions: computed(() => buggyUsePage<SharedProps>().scrollRegions),
rememberedState: computed(() => buggyUsePage<SharedProps>().rememberedState),
resolvedErrors: computed(() => buggyUsePage<SharedProps>().resolvedErrors),
})
) |
Indeed, that's exactly how it should have been implemented initially It's also a good idea to make your own composable of libraries in general, to make your code more future proof against breaking changes, so that you only need to change one instance of the code to match your own spec, instead of the 1000 of |
My current workaround:
|
This PR simplifies the
usePage()
hook in the Vue 3 adapter. We use to runcomputed()
on each value in thepage
object (in the root<App>
component):In hindsight I honestly don't know why we did this. As far as I can tell you still always need to use
usePage()
in conjunction with acomputed()
call within your own components anyway, so this is redundant. Here's what you need to do today:This would be worth it if you didn't need to still use
computed()
in your own components. But since you do, we might as well simplifyusePage
to this:Doing that makes this hook easier to consume in your own components, because you no longer need to know that
.value
is required after each top level property:To me this is much better, but it's a breaking change. Obviously we're on the brink of an official 1.0 release, so now is the time to do it. It just means a slightly more difficult upgrade process for folks.
The upgrade process would just involve removing
.value
from theirusePage()
calls:Worth it? 🤔