Back to KB
Difficulty
Intermediate
Read Time
6 min

How does VuReact compile Vue 3's withDefaults to React?

By Codcompass TeamΒ·Β·6 min read

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 Vue 3's withDefaults macro is compiled into React.

Before We Start

To keep the examples easy to read, this article follows a few simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with the API shape and core behavior of Vue 3's withDefaults.
  3. withDefaults() must be assigned to a variable.
  4. The first argument must be a defineProps() call, and the second argument must be an inline object literal.

Compilation Mapping

Vue withDefaults(defineProps<T>(), defaults) β†’ useMemo default value merge

withDefaults is a Vue 3 <script setup> utility for providing compile-time default values for props declared by defineProps. Vue's compiler generates default value logic to ensure props not passed by the parent component receive their default values. VuReact compiles this into useMemo, which merges the incoming props with the defaults during component initialization, producing a read-only props object that always contains the full set of default values.

  • Vue
<script setup lang="ts">
interface Props {
  msg?: string;
  count?: number;
  labels: string[];
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  count: 42,
  labels: () => ['one', 'two'],
});
</script>

Enter fullscreen mode Exit fullscreen mode

  • Compiled React
import { useMemo, memo } from 'react';

interface Props {
  msg?: string;
  count?: number;
  labels: string[];
}

export type ICompProps = Props;

const Input = memo((vrProps: ICompProps) => {
  /* from withDefaults */
  const props = useMemo<Readonly<Props>>(() => ({
    ...vrProps,
    msg: vrProps.msg ?? 'hello',
    count: vrProps.count ?? 42,
    labels: vrProps.labels ?? ['one', 'two'],
  }), [vrProps]);
});

Enter fullscreen mode Exit fullscreen mode

As the example shows, Vue's withDefaults is compiled into a combination of React's useMemo and the nullish coalescing operator ??. This can be broken down into three parts:

  1. Type preservation β€” The Props interface is kept as-is, and the optional/required constraints are not altered by the defaults. msg? and count? remain optional;
  2. Default value merge β€” useMemo spreads ...vrProps to retain all passed values, then fills in defaults fo

πŸŽ‰ Mid-Year Sale β€” Unlock Full Article

Base plan from just $4.99/mo or $49/yr

Sign in to read the full article and unlock all 635+ tutorials.

Sign In / Register β€” Start Free Trial

7-day free trial Β· Cancel anytime Β· 30-day money-back