Alex Vipond
SHIFT + D

Choose the right tool to define variables in Vue and React

Published 19 days ago

In Vue and React, it's super important to choose the right tool to define variables in components and composables/hooks.

The right tool will highlight key characteristics of the variable.

Characteristic
Description
type
Is it a function, primitive, DOM element, or some other non-primitive type?
reactive/non-reactive
When the value changes, will it trigger DOM updates or other side effects?
mutable/immutable
Will you write code that imperatively/directly changes the variable's value?
derived/base
It the value automatically re-computed when other reactive variables update? (If yes, it's "derived", otherwise it's considered "base" state.)
sneaky/not sneaky

(React only) Is the variable referenced in a useEffect callback that should not re-run when the variable changes?

(I call these variables "sneaky", since their main purpose is to sneak around useEffect constraints in the right situations.)

expensive/inexpensive
Is the value expensive to compute?

In Vue, for example, the shallowRef tool tells us:

  • The variable can be any type
  • The variable is shallowly reactive (deep mutations won't trigger updates, and must be avoided to keep the system predictable)
  • The variable is mutable
  • The variable is not derived

In React, if we define something with useCallback with other variables in its dependency array, that tells us:

  • The variable is a function
  • The variable is reactive
  • The variable is immutable
  • The variable is derived
  • The variable is not sneaky

When you're reading component code and trying to predict behavior, this is crucial information, and the right tool will communicate all of it.

In Vue, here are our tool choices:

  • ref
  • reactive
  • readonly
  • computed
  • shallowRef
  • shallowReactive
  • shallowReadonly
  • customRef
  • Nothing (i.e. just use const, let, or function, with plain assignment)

And in React:

  • useState
  • useMemo
  • useCallback
  • useRef
  • Nothing (i.e. just use const, let, or function, with plain assignment)

As you work with these tools, you'll get an intuition for which tool is best in any situation. But the logic behind this intuition is pretty extensive.

To help people learn this, I wrote down all the deciding factors I could think of for both Vue and React, and made a quiz to tell exactly which tool is best.

Quiz

  • Vue
  • React
Vue Quiz
Are you defining a function?
  • No
  • Yes
Your answers (0)

    One more thought for Vue developers

    In the Vue community, we got a little obsessed with the question of ref vs. reactive. I hate to rain on the parade, but that's the least important question to ask when defining a variable.

    Hopefully this blog post is a good explanation of why we should move away from that question, and what we should focus on instead. Vue has tons of excellent tools for defining variables—take advantage of them, and enjoy!

    One more thought for React developers

    The new React Compiler promises to automatically choose useMemo and useCallback whenever there's an opportunity to optimize re-render performance. We can simply define variables in plain JavaScript, and the compiler will purportedly choose the right tool for us.

    But the official React Compiler docs make zero mention of useEffect or what impact the compiler might have on our effect timing.

    IMHO, effect timing is the hardest part of web dev, and if the React Compiler doesn't automate those decisions, then we still need to be knowledgeable and careful about which tool we use to define variables.

    A final thought about multi-step forms

    This quiz was also a really good excuse to mess around with an idea I had for implementing multi-step forms with multiple conditional branches:

    1. Model the form as a list of nodes and edges, as if it were a network (because it actually is)
    2. Generate the form from the data model
    3. Collect form state in a single object
    4. To move forward through the form, use form state to traverse the network data model, computing which "node" should be active
    5. To move backward through the form, erase the most recent answer, and re-compute the active node based on the new form state

    This approach felt pretty awesome! I'm polishing the idea a bit more, and then I'll write a blog post with code examples to explore advantages and disadvantages.

    ON THIS PAGE

    Choose the right tool to define variables in Vue and ReactQuizOne more thought for Vue developersOne more thought for React developersA final thought about multi-step forms