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

fix(useRouteHash,useRouteQuery,useRouteParams): re-evaluates the value immediately #3002

Merged
merged 3 commits into from
May 9, 2023

Conversation

anteriovieira
Copy link
Member

@anteriovieira anteriovieira commented Apr 19, 2023

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.
⚠️ Slowing down new functions

Warning: Slowing down new functions

As the VueUse audience continues to grow, we have been inundated with an overwhelming number of feature requests and pull requests. As a result, maintaining the project has become increasingly challenging and has stretched our capacity to its limits. As such, in the near future, we may need to slow down our acceptance of new features and prioritize the stability and quality of existing functions. Please note that new features for VueUse may not be accepted at this time. If you have any new ideas, we suggest that you first incorporate them into your own codebase, iterate on them to suit your needs and assess their generalizability. If you strongly believe that your ideas are beneficial to the community, you may submit a pull request along with your use cases, and we would be happy to review and discuss them. Thank you for your understanding.


Description

It will re-evaluate the value immediately.

Additional context

By default, Vue.js caches the result of a computed property and only re-evaluates it if one of its dependencies has changed. But currently, it seems that it is not updating or getting the correct value on the same tick. These updates will force a re-evaluation after the value has been updated.

Example:

import { useRouteQuery } from '@vueuse/router'

const page = useRouteQuery('page', 1)
const userId = useRouteQuery('user')

const fetch = () => {
   // ... send page and userId as parameters.
}

const searchByUserId(id) {
   page.value = 1
   userId.value = id
   
   fetch()
}

live code

🤖 Generated by Copilot at a4035ad

This pull request refactors and improves the router composables useRouteHash, useRouteParams, and useRouteQuery, by enhancing their reactivity, consistency, and type support. It also adds or updates the corresponding test files to verify their functionality and behavior. Additionally, it renames the RouterQueryValue type to RouteDefaultValue to avoid confusion.

🤖 Generated by Copilot at a4035ad

  • Rename RouterQueryValue type to RouteDefaultValue to avoid confusion (link, link, link, link, link)
  • Move route-related composables from individual files to _types.ts for consistency (link, link, link)
  • Refactor useRouteHash, useRouteParams, and useRouteQuery to use local refs instead of directly modifying the route object, to improve reactivity and avoid side effects (link, link, link)
  • Add test file for useRouteHash composable, with two test cases to check the initial and updated values of the hash (link)
  • Update test file for useRouteParams composable, to import Ref type, add params argument to getRoute helper, and add two test cases to check the initial and updated values of the param (link, link, link, link)
  • Update test file for useRouteQuery composable, to import Ref type, simplify getRoute helper, and add a test case to check the updated value of the query (link, link, link, link)

@antfu
Copy link
Member

antfu commented Apr 20, 2023

I think it was on purpose to collect all changes from multiple sources and avoid conflicts

@anteriovieira
Copy link
Member Author

anteriovieira commented Apr 21, 2023

I think it was on purpose to collect all changes from multiple sources and avoid conflicts

History: #901 -> #2646 -> commit

You are right, and I followed those adjustments and worked to not break the tests. But apparently, the tests are not consistent. After your comment, I reviewed the entire code again and did some more tests, and realized that there is a break. I am working on the correction and will send it soon with more tests.

Thank you.

@anteriovieira anteriovieira marked this pull request as draft April 21, 2023 22:21
@anteriovieira anteriovieira marked this pull request as ready for review April 22, 2023 01:32
@anteriovieira
Copy link
Member Author

anteriovieira commented Apr 22, 2023

@antfu, the latest updates ensure that the route is updated with multiple sources and add more tests. You can see the code working here.

Check how the current version is working here. As you can see, the current variable value doesn't change correctly even using nextTick.

@antfu antfu changed the title fix(add-on/router): re-evaluates the value immediately fix(useRouterHash,useRouterQuery,useRouterParams): re-evaluates the value immediately Apr 22, 2023
@antfu antfu changed the title fix(useRouterHash,useRouterQuery,useRouterParams): re-evaluates the value immediately fix(useRouteHash,useRouteQuery,useRouteParams): re-evaluates the value immediately Apr 22, 2023
Copy link
Member

@antfu antfu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explaination! I left some concern here.

packages/router/useRouteQuery/index.ts Outdated Show resolved Hide resolved
packages/router/useRouteQuery/index.ts Outdated Show resolved Hide resolved
@anteriovieira anteriovieira marked this pull request as draft April 22, 2023 14:08
@anteriovieira anteriovieira marked this pull request as ready for review April 25, 2023 22:50
@anteriovieira
Copy link
Member Author

anteriovieira commented May 4, 2023

Working on multiple scope example

@antfu antfu merged commit d525244 into vueuse:main May 9, 2023
3 checks passed
@anteriovieira anteriovieira deleted the fix/@vueuse/router branch May 10, 2023 23:09
@lishaobos
Copy link

@anteriovieira i have some questions.

Firstly, this PR is causing some errors: #3173

In my understanding, if we need an immediate value and a reactive value, we can do it like this:

let isChanging = false

const ref = computed<any>({
    get() {
      const val = route.query[name]
      const newVal = _query.get(name)
      const data = (isChanging ? newVal : val) ?? defaultValue
      return transform(data as T)
    },
    set(v) {
      isChanging = true
      _query.set(name, (v === defaultValue || v === null) ? undefined : v)

      nextTick(async () => {
        await router[toValue(mode)]({
          ...route,
          query: { ...route.query, ...Object.fromEntries(_query.entries()) },
        })
        isChanging = false
      })
    },
  })

but, they do not work with scope.stop() because computed is cleaned up and cannot trigger the getter. Maybe we can change the unit test?

@anteriovieira
Copy link
Member Author

Hi @lishaobos , thanks! I'm going to investigate it.

@lishaobos
Copy link

lishaobos commented Jun 27, 2023

Hi @lishaobos , thanks! I'm going to investigate it.

😊,i have another idea, they can pass unit test

watch(() => route.query[name], (v) => {
    _query.set(name, (v === defaultValue || v === null) ? undefined : v)
    _trigger?.()
  }, {
    flush: 'sync',
    immediate: true,
  })

  return customRef<any>((track, trigger) => {
    _trigger = trigger
    return {
      get() {
        track()

        const data = _query.get(name) ?? defaultValue
        return transform(data as T)
      },
      set(v) {
        _query.set(name, (v === defaultValue || v === null) ? undefined : v)

        trigger()

        nextTick(() => {
          router[toValue(mode)]({
            ...route,
            query: { ...route.query, ...Object.fromEntries(_query.entries()) },
          })
        })
      },
    }
  })

@anteriovieira
Copy link
Member Author

Hi @lishaobos , thanks! You had a good solution for that. Sorry for the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants