question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Reactive/Store-like primitive

See original GitHub issue
// Turns properties into signals
const r = reactive({ foo: 123, bar: "hehe" });

console.log(r.foo.value);

Open question: Should conversion be deep or shallow?

Pros

  • Easy to make an existing object reactive

Cons

  • tbd

Update with assign()-syntax

// Update a Reactive with assign()-like syntax:
const r = reactive({ name: "Alice" });
update(r, { name: "Bob" });

// property 'age' does not exist in type '{ name?: string }'
update(r, { age: 42 });

// '2' has no properties in common with '{ name?: string }'
update(r, 2);

console.log(r.name.value); // "Bob"

Pros

  • Good for Redux users?

Cons

  • Ambiguity for collections/arrays: Should we update or concat?
  • Is this needed for an MVP or could this be added in users themselves? What’s the use case?
  • Risks forking update logic

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:4
  • Comments:15 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
luisherranzcommented, Oct 4, 2022

Another take at deep signals, based on Proxies.

StackBlitz with examples

I’ll refine it a bit (add tests, avoid wrapping unsupported elements and built-ins, etc) and publish an npm package so people can use it and report feedback.

I made it work as similar as possible to plain JavaScript objects, not to signals, because for my use case that’s preferable. But making it as similar as possible to signals (like @EthanStandel’s library) is also possible.

Plain JS objects

It’s using $ to return the signal instead of the value.

const App = () => {
  return (
    <div>
      {/* Pass the signal down to JSX */}
      <div>Name: {user.$name}</div>
      {/* It works, but triggers a component rerender */}
      <div>Email: {user.email}</div>
    </div>
  );
};

It writes to the signal when you update the plain object:

user.name = "Jon";

Signal-like objects

For primitives, it could always return the signal:

const App = () => {
  return (
    <div>
      {/* Pass the signal down to JSX */}
      <div>Name: {user.name}</div>
      {/* It works, but triggers a component rerender */}
      <div>Email: {user.email.value}</div>
    </div>
  );
};

And it could force people to write to the signal using .value, like:

user.name.value = "Jon";

I guess the main differences with @EthanStandel’s library, apart from the plain-JS-object API, are that it’s using lazy initialization (it creates proxies and signals on the fly) and it supports adding properties on the fly.

2reactions
EthanStandelcommented, Sep 11, 2022

I came here to recommend this and for anyone in the mean-time, I just published a package called preact-signal-store which is meant to do just this. I expose a deepSignal which takes an object and makes every atomic property a Signal and makes every parenting object a DeepSignal type. The DeepSignal type has peek and a value getter and setter that act just like Signal but it strictly reads from and writes to the underlying Signal properties lower in the tree.

I personally think this model would make sense in @preact/signals but I’m curious what maintainers and the community think

Read more comments on GitHub >

github_iconTop Results From Across the Web

I changed my mind. Angular needs a reactive primitive
A simple reactive primitive is necessary for simple, local, reactive state synchronization.
Read more >
Reactivity of primitives using reactive in Vue 3 - Stack Overflow
So just use ref as it can be used for almost everything you can even create your own types and specify them.
Read more >
Guides:Reactivity - SolidJS
Solid's data management is built off a set of flexible reactive primitives which are responsible for all the updates. It takes a very...
Read more >
Introducing Preact Signals: a reactive state primitive that is fast ...
It's hard but it feels like svelte is an inspiration here too. Without stores you get reactivity like… let dopeshit = 0; dopeshit...
Read more >
Home Rolled Store with the Vue.js Composition API
As an alternative to reactive you could use ref but I prefer reactive for this use case. ref is typically used for primitive...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found