Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/nuxtPublic

feat(nuxt): add reset to default functionality foruseState andclearNuxtState#33527

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
Harm-Nullix wants to merge8 commits intonuxt:main
base:main
Choose a base branch
Loading
fromHarm-Nullix:reset-to-init-useState

Conversation

@Harm-Nullix
Copy link

  • RefactoruseState andclearNuxtState to improve statemanagement and reset functionality, introduce_state for internal use.

🔗 Linked issue

#32117

📚 Description

The setup for this PR is a starting point with a proposed solution
It does break the current logic as it does not automatically sets the state to undefined but resets it to the giveninit function

Other paths considered:

  1. make theinit parameter aoptions object (fallback to oldinit param),
    • to define a default value alongside theinit value
    • or to flag the state to reset / not reset to undefined
  2. flip the flag that is now given toclearNuxtState to keep current logic as is.
  3. Setting a object in thestate.ts file that holds the init functions by key rather than usingnuxtApp._state

  1. I did not want to do this because it makes the function ofuseState less clear
  2. The solution and logic way of thinking resetting to a default value instead of undefined seemed more in line with Nuxt composables likeuseAsyncData
  3. I did this because it is more in line with other data objects and maybe clears the path for further improvements for the state across the whole NuxtApp.

TODO

When a solid path is determined, I will add guiding docs to the current functionality

… management and reset functionality, introduce `_state` for internal use.
@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz CodeflowRun & review this pull request inStackBlitz Codeflow.

@coderabbitai
Copy link

coderabbitaibot commentedOct 20, 2025
edited
Loading

Walkthrough

This pull request refactors Nuxt's state composable by introducingInitOption<T> andUseStateReturn<T> types, updatinguseState overloads to accept anInitOption and return a consistent ref type, and reworking hydration to store per-key default functions and internal_state entries. Initial values are resolved via a newtoValueWithFallback helper.clearNuxtState gains an optionalreset parameter and per-key clearing is factored intoclearNuxtStateByKey. The Nuxt app interface andcreateNuxtApp now include an internal_state shallowReactive map.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Type scaffolding and signature changes: Review the newInitOption<T> andUseStateReturn<T> type definitions and their impact on theuseState overloads; verify backward compatibility with existing single-parameter usage
  • Hydration and lazy resolution logic: Carefully examine the reworked hydration mechanism, particularly howdefaultFn is stored and resolved viatoValueWithFallback, ensuring it maintains correct SSR behaviour and reference integrity
  • Reset parameter semantics: Verify that the newreset parameter inclearNuxtState correctly implements the distinction between clearing and resetting, and that it aligns with existinguseAsyncData patterns
  • State synchronisation edge cases: Review test additions covering key collisions and shared keys to understand the expected interaction patterns
  • Internal_state field integration: Confirm that the new_state field on_NuxtApp integrates correctly with existing state management and SSR payload handling

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 60.00% which is insufficient. The required threshold is 80.00%.You can run@coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature: adding reset-to-default functionality for useState and clearNuxtState, aligning with the core changes throughout the changeset.
Description check✅ PassedThe description is directly related to the changeset, explaining the refactoring of useState and clearNuxtState with the new reset functionality and internal _state structure, linking to issue#32117.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between15c46a5 ande701a14.

📒 Files selected for processing (1)
  • packages/nuxt/src/app/nuxt.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Follow standard TypeScript conventions and best practices

Files:

  • packages/nuxt/src/app/nuxt.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,vue}: Use clear, descriptive variable and function names
Add comments only to explain complex logic or non-obvious implementations
Keep functions focused and manageable (generally under 50 lines), and extract complex logic into separate domain-specific files
Remove code that is not used or needed
Use error handling patterns consistently

Files:

  • packages/nuxt/src/app/nuxt.ts
🧠 Learnings (2)
📚 Learning: 2024-12-12T12:36:34.871Z
Learnt from: huang-julienRepo: nuxt/nuxt PR: 29366File: packages/nuxt/src/app/components/nuxt-root.vue:16-19Timestamp: 2024-12-12T12:36:34.871ZLearning: In `packages/nuxt/src/app/components/nuxt-root.vue`, when optimizing bundle size by conditionally importing components based on route metadata, prefer using inline conditional imports like:```jsconst IsolatedPage = route?.meta?.isolate ? defineAsyncComponent(() => import('#build/isolated-page.mjs')) : null```instead of wrapping the import in a computed property or importing the component unconditionally.

Applied to files:

  • packages/nuxt/src/app/nuxt.ts
📚 Learning: 2025-09-10T14:42:56.647Z
Learnt from: TofandelRepo: nuxt/nuxt PR: 33192File: test/nuxt/use-async-data.test.ts:366-373Timestamp: 2025-09-10T14:42:56.647ZLearning: In the Nuxt useAsyncData test "should watch params deeply in a non synchronous way", the foo watcher intentionally updates both params.foo and params.locale using locale.value, simulating a scenario where one watcher consolidates multiple reactive values into a shared params object for testing debounced/non-synchronous behavior.

Applied to files:

  • packages/nuxt/src/app/nuxt.ts
🔇 Additional comments (2)
packages/nuxt/src/app/nuxt.ts (2)

2-2:LGTM!

TheMaybeRefOrGetter import and_state initialisation are correct. The use ofshallowReactive appropriately matches the_asyncData pattern, where the top-level record tracks key additions/removals whilst individual refs handle deep reactivity.

Also applies to: 322-322


146-151:The_state._default type signature is correct as-is; no change needed.

The type_default: () => MaybeRefOrGetter<unknown> intentionally mirrors theInitOption<T> = (() => MaybeRefOrGetter<T>) pattern expected foruseState init functions. When_default() is invoked and its result passed totoValueWithFallback, Vue'stoValue() utility correctly unwraps theMaybeRefOrGetter without nested function calls or type ambiguity. The difference from_asyncData._default: () => unknown reflects the distinct use cases: asyncData handlers return plain resolved values, whilst state init handlers support flexible input types (plain values, refs, or getters).

Likely an incorrect or invalid review comment.

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the@coderabbitai full review command to re-trigger a full review. If the issue persists, setpath_filters to include or exclude specific files.


Thanks for usingCodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment@coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nuxt/src/app/composables/state.ts (1)

65-76:Safer key derivation and leaner payload clearing

  • _allKeys should only include$s-prefixed entries; otherwise non‑useState keys (if any) would be transformed and re‑prefixed, causing unintended clears.
  • When removing without reset, prefer deleting the key to avoid retaining enumerableundefined slots (keeps payload slim and prevents stale keys from reappearing in subsequent clears).

Apply:

-  const _allKeys = Object.keys(nuxtApp.payload.state)-    .map(key => key.substring(useStateKeyPrefix.length))+  const _allKeys = Object.keys(nuxtApp.payload.state)+    .filter(key => key.startsWith(useStateKeyPrefix))+    .map(key => key.substring(useStateKeyPrefix.length))   for (const _key of _keys) {-    clearNuxtStateByKey(nuxtApp, useStateKeyPrefix + _key, reset ?? true)+    clearNuxtStateByKey(nuxtApp, useStateKeyPrefix + _key, reset ?? true)   }

And streamline per‑key clearing:

-function clearNuxtStateByKey (nuxtApp: NuxtApp, key: string, reset: boolean): void {-  if (key in nuxtApp.payload.state) {-    nuxtApp.payload.state[key] = undefined-  }--  if (nuxtApp._state[key]) {-    nuxtApp._state[key]!.data.value = reset ? unref(nuxtApp._state[key]!._default()) : undefined-  }-}+function clearNuxtStateByKey (nuxtApp: NuxtApp, key: string, reset: boolean): void {+  if (reset) {+    if (nuxtApp._state[key]) {+      // Resets both _state data and payload via toRef linkage+      nuxtApp._state[key]!.data.value = unref(nuxtApp._state[key]!._default())+      return+    }+    // No _state registered: remove from payload if present+    delete nuxtApp.payload.state[key]+  } else {+    // Remove from payload and null out internal value if tracked+    delete nuxtApp.payload.state[key]+    if (nuxtApp._state[key]) {+      nuxtApp._state[key]!.data.value = undefined+    }+  }+}
🧹 Nitpick comments (2)
packages/nuxt/src/app/nuxt.ts (1)

145-151:Internal _state map looks good; consider GC of stale keys

The addition is well‑typed and initialised correctly. To avoid long‑lived growth on the client, consider pruning entries (e.g. delete nuxtApp._state[key]) when a state is cleared without reset and no watchers remain. This keeps memory proportional to active state keys.

Also applies to: 319-319

packages/nuxt/src/app/composables/state.ts (1)

45-56:You can simplify to a plain ref; computed indirection is unnecessary

Given_state[key] andstate are established above, returningstate as Ref<T> is sufficient. The computed fallback tonuxtApp.payload.state[key] is dead code in this path and adds overhead.

Apply:

-  return computed({-    get () {-      return nuxtApp._state[key]?.data.value ?? nuxtApp.payload.state[key]-    },-    set (value) {-      if (nuxtApp._state[key]) {-        nuxtApp._state[key]!.data.value = value-      } else {-        nuxtApp.payload.state[key] = value-      }-    },-  })+  return state as Ref<T>

If you keep the computed, consider at least collapsing the branches tostate.value for both get/set. As per coding guidelines.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between568cd34 ande7b2a3b.

📒 Files selected for processing (3)
  • packages/nuxt/src/app/composables/state.ts (2 hunks)
  • packages/nuxt/src/app/nuxt.ts (2 hunks)
  • test/nuxt/composables.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Follow standard TypeScript conventions and best practices

Files:

  • packages/nuxt/src/app/nuxt.ts
  • test/nuxt/composables.test.ts
  • packages/nuxt/src/app/composables/state.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Write unit tests for core functionality usingvitest

Files:

  • test/nuxt/composables.test.ts
🧬 Code graph analysis (2)
test/nuxt/composables.test.ts (2)
packages/nuxt/src/app/composables/state.ts (2)
  • clearNuxtState (60-77)
  • useState (20-57)
packages/nuxt/src/app/nuxt.ts (1)
  • useNuxtApp (557-570)
packages/nuxt/src/app/composables/state.ts (1)
packages/nuxt/src/app/nuxt.ts (2)
  • useNuxtApp (557-570)
  • NuxtApp (206-206)
🔇 Additional comments (1)
test/nuxt/composables.test.ts (1)

203-207:Test coverage aligns with intended semantics

The scenarios comprehensively cover payload registration, unwrapped defaults, shared-key behaviour, and reset/remove paths. These rely on useState unref’ing the init return on initialisation; see my comment in state.ts proposing that fix.

Also applies to: 212-216, 217-224, 225-234, 243-285, 286-344

@codspeed-hq
Copy link

codspeed-hqbot commentedOct 20, 2025
edited
Loading

CodSpeed Performance Report

Merging#33527 willdegrade performances by 13.81%

ComparingHarm-Nullix:reset-to-init-useState (e701a14) withmain (f171385)

Summary

❌ 1 regression
✅ 9 untouched

⚠️Please fix the performance issues oracknowledge them on CodSpeed.

Benchmarks breakdown

BenchmarkBASEHEADChange
writeTypes in the basic-types fixture80.9 ms93.9 ms-13.81%

@pkg-pr-new
Copy link

pkg-pr-newbot commentedOct 20, 2025
edited
Loading

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@33527

@nuxt/nitro-server

npm i https://pkg.pr.new/@nuxt/nitro-server@33527

nuxt

npm i https://pkg.pr.new/nuxt@33527

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@33527

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@33527

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@33527

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@33527

commit:e701a14

@Harm-Nullix
Copy link
Author

Quick example addition:

<script setup lang="ts">import { useState } from '#app'const stateWithoutKeyAndInit = useState<number | undefined>()const stateWithKeyWithoutInit = useState<number | undefined>('WithKeyWithoutInit')const stateWithoutKeyWithInit = useState<any>(() => ({  spamm: 'eggs',  green: 'ham',  value: 1,}))const stateWithKeyWithInit = useState<any>('WithKeyWithInit', () => ({  spamm: 'eggs',  green: 'ham',  value: 1,}))const resetState = (keys?: string | string[]) => {  clearNuxtState(keys)}const reload = () => window.location.reload()const state1 = useState('key', () => ref({  test: 1,}))const state2 = useState('key', () => ref({  test: 2,}))console.debug('state1.value :: ', state1.value.test)console.debug('state2.value :: ', state2.value.test)state1.value.test = 3</script><template>  <!-- Edit this file to play around with Nuxt but never commit changes! -->  <div>    Nuxt Playground    <button @click="resetState()">      Reset state    </button>    <button @click="reloadNuxtApp()">      reload nuxt app    </button>    <button @click="reload()">      reload window    </button>  </div>  <div>    <ul>      <li>        stateWithoutKeyAndInit :: {{ stateWithoutKeyAndInit }}        <button @click="stateWithoutKeyAndInit = stateWithoutKeyAndInit ? stateWithoutKeyAndInit + 1 :1 ">          set state        </button>      </li>      <li>        stateWithKeyWithoutInit :: {{ stateWithKeyWithoutInit }}        <button @click="stateWithKeyWithoutInit = stateWithKeyWithoutInit ? stateWithKeyWithoutInit + 1 :1 ">          set state        </button>      </li>      <li>        stateWithoutKeyWithInit :: {{ stateWithoutKeyWithInit }} <button @click="stateWithoutKeyWithInit.value += 1">          set state        </button>      </li>      <li>        stateWithKeyWithInit :: {{ stateWithKeyWithInit }} <button @click="stateWithKeyWithInit.value += 1">          set state        </button>      </li>    </ul>    {{ state1 }}. -- <br><br><br>    {{ state2 }}  </div></template><style scoped></style>

Copy link
Member

@huang-julienhuang-julien left a comment

Choose a reason for hiding this comment

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

I think that it can be really confusing for users and quite hard to debug if there's multipleuseState that retuns differents default values

@Harm-Nullix
Copy link
Author

I think that it can be really confusing for users and quite hard to debug if there's multipleuseState that retuns differents default values

I agree,
That is how states currently work right?
If you use a key twice, the seconduseState will just return the current payload of the firstuseState.

E.g.asyncData has the same logic: When you useasyncData with a default value, and the same key is used based on the url, you will get a other default value (or the current transformed value) from the other component that makes the same call, and not your own default.

You can tackle this by creating a composable around youruseState as recommended that would be in charge of this specific key.

I think it is a valid point about data storage and the keys that are being used, I've come across this myself while useingUseFetch with autokeys, but I also think that topic is too brought to pick up in such a change as this, wouldn't you agree?

@Harm-Nullix
Copy link
Author

So what is next?
I am a bit lost in what to do with this now.
I feel like I made a clear case to at least discus.

  • I am not certain of how the PR flow goes (beyond the defaults)

@huang-julien
Copy link
Member

Yes that's just how it currently works with useAsyncData.
I think we can move on with this PR. I'll trigger a discussion with the team but this is probably the best solution.

constuseStateKeyPrefix='$s'
constgetDefault=()=>undefined

typeInitOption<T>=(()=>T|Ref<T>)
Copy link
Member

Choose a reason for hiding this comment

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

You can useMaybeRefOrGetter instead

Copy link
Author

Choose a reason for hiding this comment

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

Nice one, added


returncomputed({
get(){
returnnuxtApp._state[key]?.data.value??nuxtApp.payload.state[key]
Copy link
Member

Choose a reason for hiding this comment

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

We probably don't want to have two possible reference for a state 🤔

Copy link
Author

Choose a reason for hiding this comment

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

Agreed, I've updated that to the state ref

if(keyinnuxtApp.payload.state){
nuxtApp.payload.state[key]=undefined
}
clearNuxtStateByKey(nuxtApp,useStateKeyPrefix+_key,reset??true)
Copy link
Member

@huang-julienhuang-julienOct 29, 2025
edited
Loading

Choose a reason for hiding this comment

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

Let's avoid breaking changes. We can make it true by default for v5 though by using a future flag

Copy link
Author

Choose a reason for hiding this comment

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

Agreed, toggled the flag to be false bd

Copy link
Author

@Harm-NullixHarm-NullixNov 10, 2025
edited
Loading

Choose a reason for hiding this comment

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

@huang-julien , is this something I can add to project as a future change, lets say as experimental?
It feels "intrusive" to do so in the Nuxt project.

Copy link

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
packages/nuxt/src/app/composables/state.ts (5)

9-10:Simplify type alias or rename to avoid confusion.

UseStateOptions<T> suggests an options object with multiple properties, but it's merely an alias forInitOption<T> (a function type). This naming can mislead users and maintainers.

Consider either:

  • UsingInitOption<T> directly throughout, or
  • Renaming toUseStateInit<T> to reflect that it's a single init function rather than a structured options object.

Apply this diff to useInitOption<T> directly:

-type InitOption<T> = (() => MaybeRefOrGetter<T>)-type UseStateOptions<T> = InitOption<T>+type InitOption<T> = () => MaybeRefOrGetter<T>

Then replaceUseStateOptions<T> withInitOption<T> on lines 18, 19, and 25.


21-24:Clarify the autoKey handling logic.

The autoKey extraction and re‑insertion logic is difficult to follow. The code pops the last argument if it's a string, then conditionally unshifts it back ifargs[0] is not a string. This approach is fragile and not immediately clear to maintainers.

Consider refactoring for clarity, or at minimum add inline comments explaining the intended argument patterns (e.g.,(key, init),(init),(key), etc.) and how this logic resolves them.


45-45:Type assertion bypasses overload return‑type differences.

Theas Ref<T> assertion reconciles two overloads that declare different return types (Ref<UnwrapRef<T>> vsRef<T>). Whilst the runtime behaviour is correct (values are unwrapped viatoValue), this assertion may obscure type‑checking issues and could lead to subtle inference problems for callers.

If the inconsistency (flagged earlier) is intentional, consider documenting why the types differ; otherwise, unify the return types to eliminate the need for this assertion.


69-77:Potential redundancy and intermediate state flicker when resetting.

Whenreset is true andnuxtApp._state[key] exists, the code performs two assignments:

  1. Line 71 setsnuxtApp.payload.state[key] = undefined (directly on the object)
  2. Line 75 setsnuxtApp._state[key]!.data.value = toValue(...) (through the ref)

Since_state[key].data is atoRef topayload.state[key] (created on line 36/38), they reference the same underlying value. The assignment on line 71 may cause an intermediateundefined state before line 75 overwrites it with the default, potentially triggering watchers or causing a visual flicker.

Consider skipping the line 71 assignment when_state[key] exists andreset is true, or reordering to set the reset value first.

Apply this diff to avoid the intermediate state:

 function clearNuxtStateByKey (nuxtApp: NuxtApp, key: string, reset: boolean): void {-  if (key in nuxtApp.payload.state) {-    nuxtApp.payload.state[key] = undefined-  }-   if (nuxtApp._state[key]) {     nuxtApp._state[key]!.data.value = reset ? toValue(nuxtApp._state[key]!._default) : undefined+  } else if (key in nuxtApp.payload.state) {+    // Clear legacy state entries that lack _state registry+    nuxtApp.payload.state[key] = undefined   } }

41-43:Consider error handling for init function execution.

The code callstoValue(defaultFn) (line 42) without catching potential errors. If the init function throws during initial hydration or reset, the exception will propagate and could break the component or app.

Consider wrapping thetoValue call (here and on line 75) in a try‑catch to provide a more helpful error message or graceful fallback.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between78ef915 and20af136.

📒 Files selected for processing (1)
  • packages/nuxt/src/app/composables/state.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Follow standard TypeScript conventions and best practices

Files:

  • packages/nuxt/src/app/composables/state.ts
🧬 Code graph analysis (1)
packages/nuxt/src/app/composables/state.ts (1)
packages/nuxt/src/app/nuxt.ts (2)
  • useNuxtApp (557-570)
  • NuxtApp (206-206)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: code
  • GitHub Check: build
🔇 Additional comments (4)
packages/nuxt/src/app/composables/state.ts (4)

1-3:LGTM! Imports support new functionality.

The added imports (MaybeRefOrGetter,UnwrapRef,toValue, andNuxtApp type) are all used appropriately throughout the refactored code.


18-19:Verify the return‑type inconsistency between overloads.

The first overload returnsRef<UnwrapRef<T>> whilst the second returnsRef<T>. Since both code paths usetoValue(defaultFn) (line 42) to unwrapMaybeRefOrGetter<T>, both should exhibit the same unwrapping behaviour at runtime. This type mismatch may cause TypeScript inference issues when the key is omitted or auto-generated.

Confirm whether both overloads should returnRef<UnwrapRef<T>> for consistency, or clarify why they differ.


49-67:LGTM!clearNuxtState correctly delegates to per‑key helper.

The addition of thereset parameter and delegation toclearNuxtStateByKey maintains clarity. Defaultingreset tofalse preserves existing behaviour for callers who don't opt in to the new reset feature.


37-40:No action required—_state is properly defined and initialised.

Verification confirms that_state is correctly defined in the_NuxtApp interface (line 146–150, packages/nuxt/src/app/nuxt.ts) with the expected structure:Record<string, { data: Ref<unknown>, _default: () => MaybeRefOrGetter<unknown> } | undefined>. It is initialised increateNuxtApp (line 319) asshallowReactive({}), and the code at lines 37–40 correctly assigns the expected structure.

@Harm-Nullix
Copy link
Author

@huang-julien , I think I have done everything needed to make this:
A: compatible with what is working right now.
B: made it able to set a default value/getter that is used if wanted.

Please let me know if anything is needed on my side to move things along.

Copy link

@coderabbitaicoderabbitaibot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
docs/4.api/3.utils/clear-nuxt-state.md (1)

12-14:Improve sentence structure for clarity.

The phrase "initial value passing a second parameter" is grammatically awkward. Consider adding a comma or rephrasing for better readability.

Apply this diff to improve the grammar:

-You can also reset the state to the initial value passing a second parameter+You can also reset the state to the initial value by passing a second parameter
packages/nuxt/src/app/composables/state.ts (2)

25-25:Consider stronger type safety for the destructuring.

The type assertionas [unknown, InitOption<T>] bypasses TypeScript's type checking. Given the complex autoKey logic above, this could mask runtime errors ifargs doesn't have the expected shape.

Consider either:

  1. Simplifying the argument handling logic to make the types provable, or
  2. Adding runtime validation to ensureargs matches the expected structure before destructuring.

82-89:Consider using Nuxt's logger instead of console.error.

Theconsole.error on line 86 logs errors directly to the console. For consistency with Nuxt's logging patterns and better control in production environments, consider using a Nuxt logger utility if available.

This is a minor suggestion since the error case (init function throwing) should be rare.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between20af136 and15c46a5.

📒 Files selected for processing (3)
  • docs/4.api/3.utils/clear-nuxt-state.md (1 hunks)
  • packages/nuxt/src/app/composables/state.ts (2 hunks)
  • packages/nuxt/src/app/nuxt.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/nuxt/src/app/nuxt.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/nuxt/src/app/composables/state.ts (1)
packages/nuxt/src/app/nuxt.ts (2)
  • useNuxtApp (559-572)
  • NuxtApp (208-208)
🪛 LanguageTool
docs/4.api/3.utils/clear-nuxt-state.md

[uncategorized] ~13-~13: Possible missing comma found.
Context: ...can also reset the state to the initial value passing a second parameter : ## Type ...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~24-~24: Loose punctuation mark.
Context: ...lean): void ``` ## Parameters -keys: One or an array of keys that are used i...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~25-~25: Loose punctuation mark.
Context: ...l state** will be invalidated. -reset: Reset the state to the initial value pa...

(UNLIKELY_OPENING_PUNCTUATION)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: code
  • GitHub Check: docs
🔇 Additional comments (5)
packages/nuxt/src/app/composables/state.ts (5)

1-10:LGTM! Clean type definitions and imports.

The import updates align with Vue 3 best practices, and the new type definitions (InitOption<T>,UseStateReturn<T>) clearly express the API surface. ThegetDefault helper is straightforward.


33-43:LGTM! State initialisation logic is solid.

The internal_state tracking and deferred initialisation usingtoValueWithFallback correctly handle both the initial setup and future reset scenarios. The previous concern about nested refs has been addressed.


49-67:LGTM! Clear and backward-compatible API extension.

Thereset parameter is properly defaulted tofalse, maintaining backward compatibility whilst enabling the new reset-to-init behaviour. The delegation toclearNuxtStateByKey keeps the logic clean.


69-76:LGTM! Proper handling of both tracked and legacy state.

The function correctly handles both_state-tracked entries and legacy entries without registry, ensuring smooth backward compatibility and migration paths.


21-24:Remove the unused autoKey logic—it contradicts the type signatures and is never executed.

Based on verification across the codebase, theautoKey extraction (lines 21–24) is dead code. The type signatures guarantee that the last argument is either anInitOption<T> (a function) or undefined, never a string. All 30+ real-world calls follow the documented overload patterns (useState('key', () => init) oruseState(() => init)), and none pass a string as the final parameter.

Delete lines 21–24 and update the implementation to directly destructure args:

exportfunctionuseState<T>(...args:any):UseStateReturn<T>{const[_key,init]=args.length===1&&typeofargs[0]!=='string'     ?[undefined,args[0]]     :argsas[unknown,InitOption<T>]

Then throw the existing error if_key is missing, which will handle theuseState(init) case properly.

@danielroedanielroe added this to the4.3 milestoneDec 16, 2025
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@coderabbitaicoderabbitai[bot]coderabbitai[bot] left review comments

@danielroedanielroeAwaiting requested review from danielroedanielroe is a code owner

@huang-julienhuang-julienAwaiting requested review from huang-julien

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Projects

None yet

Milestone

4.3

Development

Successfully merging this pull request may close these issues.

3 participants

@Harm-Nullix@huang-julien@danielroe

[8]ページ先頭

©2009-2025 Movatter.jp