Skip to content

Svelte 5: $derived usage in class depending on constructor args is convoluted #11116

Closed
@brunnerh

Description

@brunnerh

Describe the problem

When reactively passing data to a class it has to be wrapped in a function or object. The class internally might want to use $derived to access it, but since that is currently only possible in a property initializer, any value passed into the constructor has to be stored in a separate property first.

E.g.

class Doubler {
    #operandFn = $state();
    operand = $derived(this.#operandFn());

    result = $derived(2 * this.operand);

    constructor(getOperand) {
        this.#operandFn = getOperand;
    }
}

let operand = $state(3);
const doubler = new Doubler(() => operand);

REPL

Describe the proposed solution

Possibly allow reactive assignments in constructors:

  class Doubler {
-     #operandFn = $state();
-     operand = $derived(this.#operandFn());
  
      result = $derived(2 * this.operand);
  
      constructor(getOperand) {
-         this.#operandFn = getOperand;
+         this.operand = $derived.by(getOperand);
      }
  }

If the operand does not need its own property:

  class Doubler {
-     #operandFn = $state();
-     operand = $derived(this.#operandFn());
  
-     result = $derived(2 * this.operand);
  
      constructor(getOperand) {
-         this.#operandFn = getOperand;
+         this.result = $derived(2 * getOperand());
      }
  }

(Don't know if this is feasible or really worth it, but wanted to make a note of this.)

Importance

nice to have

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions