It re-invokes the entire render function of the component so that the state in the component (meaning not externalized to a hook or declared outside of the component) is effectively wiped out.

Vue and Svelte don't work that way.

In a Vue SFC, this is fine:

<script setup>
let counter = 0 <-- This code only runs once

watch (someRef, () => { <-- Only this code runs when someRef changes
counter++
console.log(counter)
})

const fn = () => { ... } <-- Normal functions are stable
function fn2 () { ... } <-- Stable as well
</script>

Basically, it behaves like you would expect normal JS closures to behave because the `setup` function is invoked only once. When `someRef` changes, only the `watch` function is executed (this is also why Vue and Svelte perform better because they can execute a smaller subset of code on updates).

JS and DOM itself work with the same conceptual model, right?

<button onclick="handler()">...</button>

<script>
let counter = 0 <-- Allocated once

function handler() { } <-- Only this code is executed

const fn = () => { ... } <-- Allocated once
</script>

In React, this (obviously trivial example) doesn't work:

export const App = () => {
let counter = 0 <-- New allocation on each render

const fn = () => { ... } <-- New allocation on each render

// ...
}

Because the entire `App()` function gets invoked again. So you have to use hooks to move state out of the path of the component function because the entire component function is re-invoked. Imagine if React, instead of invoking the entire `App()` function, only invoked the code affected by the change as captured in the dependency array. That's how Vue and Svelte work; the same way that a handler function via `addEventListener()` only executes the designated handler function. React does not work this way. Think hard about that and how React is conceptually opposite of how events work in DOM itself.

This difference in design means that in Vue, there is -- in practice -- almost never a need to do manual memoization and never really a thought of "where should I put this"?

It might seem obvious here, right? if `fn` has no dependencies on the component state, then it can just be moved out of the `App()` function. But this is a common mistake and it ends up with excess stack allocations (also why React is generally the poorest performer when it comes to memory usage).

React's model is a bit of an outlier for UIs which generally assume state encapsulated by a component is stable. React says "no, the component function is going to be invoked on every change so you cannot have state in the component."

A different way to think about this is to go look at game engines or desktop UI frameworks which render stateful objects onto a canvas and see how many game engines or UI engines assume that your object is recreated each time. This is certainly true of the underlying render buffer of the graphics card, right? But generally the developer builds on top of stateful abstractions. React has, in fact, moved the complexity onto the developer to properly place and manage state (while not being faster nor more memory efficient than Vue or Svelte).

I believe that a lot of React's expanding complexity flows from this design decision to model inherently stateful UIs in a "pretend everything is a stateless function" way because it is fundamentally playing opposite day against the underlying JavaScript and DOM.