Introduction
Vue 3's computed() is a powerful derived-state API that ensures efficient dependency tracking and recomputation. This article explores how VuReact compiles this feature into React's ecosystem, providing a streamlined transition for developers familiar with Vue.
Simplified Conventions
To maintain clarity, examples provided are simplified to focus on core logic, assuming a foundational understanding of Vue 3's computed() functionality.
Vue computed() to React useComputed()
Vue's computed() is utilized for declaring derived states with automatic dependency tracking, only recalculating when its reactive sources change. VuReact mirrors this with useComputed(), a React Hook that preserves this model.
Vue Example
<script setup>
import { reactive, computed } from 'vue';
const state = reactive({
count: 1,
price: 99,
});
const totalPrice = computed(() => state.count * state.price);
</script>
React Compilation
import { useReactive, useComputed } from '@vureact/runtime-core';
const state = useReactive({
count: 1,
price: 99,
});
const totalPrice = useComputed(() => state.count * state.price);
In this conversion, Vue's computed() directly maps to React's useComputed(), maintaining automatic tracking and caching.
TypeScript Compatibility
VuReact ensures TypeScript type safety is preserved during compilation, allowing seamless type inference in React.
Vue with TypeScript
<script lang="ts" setup>
import { reactive, computed } from 'vue';
const state = reactive({
count: 1,
price: 99,
});
const totalPrice = computed<number>(() => state.count * state.price);
</script>
React Compilation
import { useReactive, useComputed } from '@vureact/runtime-core';
const state = useReactive({
count: 1,
price: 99,
});
const totalPrice = useComputed<number>(() => state.count * state.price);
The type annotations remain intact, ensuring the generated React code stays type-safe without manual adjustments.
Writable Computed Properties
Vue's writable computed properties, using the get/set pattern, are also supported in VuReact, facilitating two-way data binding.
Vue Writable Computed Example
<script setup>
import { reactive, computed } from 'vue';
const state = reactive({
firstName: 'John',
lastName: 'Smith',
});
const fullName = computed({
get: () => `${state.firstName} ${state.lastName}`,
set: (val: string) => {
const [first, last] = val.split(' ');
state.firstName = first || '';
state.lastName = last || '';
},
});
</script>
React Compilation
import { useReactive, useComputed } from '@vureact/runtime-core';
const state = useReactive({
firstName: 'John',
lastName: 'Smith',
});
const fullName = useComputed({
get: () => `${state.firstName} ${state.lastName}`,
set: (val: string) => {
const [first, last] = val.split(' ');
state.firstName = first || '';
state.lastName = last || '';
},
});
VuReact's useComputed() supports these writable semantics, enabling synchronized updates between derived and reactive states.
Conclusion
VuReact effectively bridges Vue 3's computed() API to React's architecture, allowing developers to leverage the benefits of automatic dependency tracking and cached recomputation without sacrificing type safety or writable state capabilities.