VuReact is a compiler toolchain for migrating from Vue to React — and for writing React with Vue 3 syntax.
In this article, we will look at how VuReact optimizes top-level constants and variables when compiling Vue 3 code to React.
Before We Start
To keep the examples easy to read, this article follows two simple conventions:
- All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
- The discussion assumes you are already familiar with top-level
constdeclarations and variable optimization in Vue 3.
Compilation Mapping
Top-level Vue const -> static hoisting outside the React component
In Vue, top-level constants inside <script setup> are often used for static configuration, default values, and fixed flags.
VuReact performs static analysis on these declarations. If the initializer is a simple literal such as a string, number, or boolean, it can be hoisted outside the React component so it is not recreated on every render.
- Vue
<script setup lang="ts">
const defaultValue = 1;
const isEnabled = true;
</script>
- Compiled React
const defaultValue = 1;
const isEnabled = true;
const Comp = memo(() => {
return <></>;
});
For simple top-level constants, VuReact lifts the value out of the component body and avoids repeated initialization during re-renders.
Top-level computed variables -> React useMemo() with automatic dependency analysis
When a top-level variable is derived from an expression that depends on reactive state, VuReact can compile it into useMemo() and generate the dependency array automatically.
Purely static expressions are left as normal values instead of being wrapped unnecessarily.
- Vue
<script setup lang="ts">
const count = ref(0);
const state = reactive({ foo: 'bar', bar: { c: 1 } });
const memoizedObj = {
title: 'test',
bar: count.value,
add: () => {
state.bar.c++;
},
};
const staticObj = {
foo: 1,
state: { bar: { c: 1 } },
};
const reactiveList = [count.value, 1, 2];
</script>
- Compiled React
const count = useVRef(0);
const state = useReactive({ foo: 'bar', bar: { c: 1 } });
const memoizedObj = useMemo(
() => ({
title: 'test',
bar: count.value,
add: () => {
state.bar.c++;
},
}),
[count.value, state.bar.c],
);
const staticObj = {
foo: 1,
state: {
bar: { c: 1 },
},
};
const reactiveList = useMemo(() => [count.value, 1, 2], [count.value]);
In this example:
-
memoizedObjbecomesuseMemo()because it depends oncount.valueandstate.bar.c. -
staticObjstays a normal static object because it does not depend on reactive state. -
reactiveListis also compiled intouseMemo()with an automatically generated dependency array.
That gives React the memoization it needs without forcing developers to write dependency logic by hand.
Top comments (0)