Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): useConstant, createSignal, createComputed$ #6319

Merged
merged 3 commits into from
May 27, 2024
Merged

Conversation

wmertens
Copy link
Member

@wmertens wmertens commented May 15, 2024

This adds the following APIs:

  • useConstant(value): stores a fixed value for the lifetime of the component
  • createSignal(value): same as useSignal but can be called a variable amount of times and always returns a new Signal
  • createComputed$(cb): same as createSignal but for computed signals

Note that the create* API calls still need to run within the component context. This is only available inside the render function and the useConst callback.

Perhaps we should also make the context available inside tasks, as long as we forbid calling hooks (by forbidding useSequentialContext).

Example:

  const signals = useConstant(() => {
    const arr: (Signal<number> | string)[] = [];
    for (let i = 0; i < 10; i++) {
      arr.push(createSignal(0));
      arr.push(", ");
    }
    return arr;
  });
  const doubles = useConstant(() =>
    signals.map((s: Signal<number> | string) =>
      typeof s === "string" ? s : createComputed$(() => s.value * 2),
    ),
  );

TODO

  • make createSignal work at any time. Does it really need the container context?
  • make createComputed$ not need a Task so it's not bound to an element, or else don't add this yet. Ideally, the qrl is called and cached in the getter, and when one of the used signals changes the cache is cleared and subs triggered.

Copy link

netlify bot commented May 15, 2024

Deploy Preview for qwik-insights ready!

Name Link
🔨 Latest commit ad15e34
🔍 Latest deploy log https://app.netlify.com/sites/qwik-insights/deploys/6646b8230eee3b000865244e
😎 Deploy Preview https://deploy-preview-6319--qwik-insights.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

cloudflare-pages bot commented May 15, 2024

Deploying qwik-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: ad15e34
Status: ✅  Deploy successful!
Preview URL: https://b43a090e.qwik-8nx.pages.dev
Branch Preview URL: https://createsignal.qwik-8nx.pages.dev

View logs

PatrickJS
PatrickJS previously approved these changes May 15, 2024
thejackshelton
thejackshelton previously approved these changes May 16, 2024
@PatrickJS PatrickJS changed the title feat(core): useConst, createSignal, createComputed$ feat(core): useConstant, createSignal, createComputed$ May 17, 2024
@wmertens wmertens requested review from mhevery and removed request for maiieul May 17, 2024 05:36
@wmertens wmertens marked this pull request as draft May 18, 2024 06:59
Copy link
Contributor

@mhevery mhevery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

Copy link
Member

@gioboa gioboa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You rock 🚀

@PatrickJS
Copy link
Member

@wmertens can we merge this and have the TODO in another PR?

@wmertens wmertens dismissed stale reviews from thejackshelton and PatrickJS via ad15e34 May 25, 2024 14:56
@wmertens wmertens marked this pull request as ready for review May 27, 2024 16:32
@wmertens wmertens requested review from a team as code owners May 27, 2024 16:32
@wmertens wmertens merged commit f51259b into main May 27, 2024
33 checks passed
@wmertens wmertens deleted the createSignal branch May 27, 2024 16:34
@wmertens
Copy link
Member Author

wmertens commented May 27, 2024

I merged because I think the API will remain the same even though we'll be able to call it in more places.

Here's how to use it dynamically within the component render function. This could also be part of a hook function that forces rerenders.

import { component$, useConstant, createSignal, useSignal, useTask$ } from '@builder.io/qwik';

export default component$(() => {
  const rerender = useSignal(0)
  // force rerender by referencing the signal in the render body
  console.log('render', rerender.value)

  const sigs = useConstant([])

  sigs.push(createSignal(0))

  useTask$(({track}) => {
    track(rerender)
    for (const s of sigs) s.value++
  })

  return (
    <main>
      <div>Counts: {sigs.map(s => <span>{s.value}, </span>)}</div>
      <p>
        <button onClick$={() => rerender.value++}>Click</button>
      </p>
    </main>
  );
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants