#Losing reactivity when importing a signal from a library that uses SolidJS

16 messages ยท Page 1 of 1 (latest)

restive solar
#

Hey ๐Ÿ‘‹
I have a library that uses SolidJS, and a few projects that import said library.
I have the following code in one of my library's util files:

import { createEffect, createSignal } from "solid-js";
import Vec2 from "./data/Vec2";

export const [windowSize, setWindowSize] = createSignal<Vec2>(
  Vec2.of(window.innerWidth, window.innerHeight),
);

createEffect(() => {
  console.log("lib", windowSize());
});

createEffect(() => {
  const onResize = () => setWindowSize(Vec2.of(window.innerWidth, window.innerHeight));
  window.addEventListener("resize", onResize);
  return () => window.removeEventListener("resize", onResize);
});

and the Vec2 class that I'm using (with all the other irrelevant methods removed, to keep the code snippet short):

export default class Vec2 {
  public x: number;
  public y: number;

  private constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }

  public static of(x: number, y: number): Vec2 {
    return new Vec2(x, y);
  }
}

The code above works as expected inside the library; When the window is resized, the signal updates, and the console.log effect gets called.
The issue I have is inside another project, that imports my library. The effects there doesn't get called after the initial render.

Here's my index.tsx entrypoint in the example project, it's more-or-less the default one when setting up a new SolidJS project:

import { render } from "solid-js/web";
import App from "./App";

const root = document.getElementById("root");

if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
  throw new Error(
    "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?",
  );
}

render(() => <App />, root!);

And the App.tsx:

import { type Component, createEffect } from "solid-js";
import { windowSize } from "nodeflow-lib";

const App: Component = () => {
  createEffect(() => {
    console.log("proj", windowSize());
  });

  return <h1>Test</h1>;
};

export default App;

Any hints on why the effect inside the example app only gets called once (on load), while the one inside the library works as intended?

#

Losing reactivity when importing a signal from a library that uses SolidJS

lost harbor
#

You're showing code, but you're not showing where, or how it's imported. Neither yourindex.tsx nor App.tsx appear to have any imports that relate to the code defined at the top.

restive solar
#

As for the exporting, give me a sec...

#

in the library, in src/index.ts (the entrypoint), I'm exporting everything from my utils dir

export * from "./utils";

and then in the src/utils/index.ts im exporting the screen-utils:

export * from "./screen-utils";
tired tartan
restive solar
restive solar
lost harbor
#

Well... the answer is, something outside of what you've posted.

#

Works just fine in the playground.

restive solar
restive solar
#

@lost harbor here's a minimally reproducable version:
https://codesandbox.io/p/devbox/practical-vaughan-lwjs4f

the main directory is the library containing the screen size logic
the example/ directory contains the currently running project

first text is the imported signal
2nd line is a component that does the same, but inside the library

lost harbor
#

My best guess is that the bundling process is messing something up, since importing from a clone of the source repo works fine, and importing from the npm package doesn't. Exact same test code, just toggling the path of the import statement.
Unfortunately that's a little beyond my knowledge to debug.

restive solar
#

Alright, thanks anyway. I'll see if I can zero in on exactly what's causing the issue. hopefully its just a bundler misconfiguration and not an issue with solidjs