Learning Leptos: Build a fine-grained reactive system in 100 lines of code

แชร์
ฝัง
  • เผยแพร่เมื่อ 22 ธ.ค. 2024

ความคิดเห็น •

  • @solid_js
    @solid_js 2 ปีที่แล้ว +171

    Big fine-grained reactivity fan over here!!!!! ❤❤❤❤

  • @thecodeburger
    @thecodeburger ปีที่แล้ว +8

    Wow, one of the easiest voices to listen to on TH-cam! Thanks for the video, I'm excited to start my Leptos journey!

  • @bolt7
    @bolt7 2 ปีที่แล้ว +35

    Thanks, this really demystified the concepts for me. Various pointer types aside it's quite intuitively organized. Big fan of Leptos, I've tinkered with a few Rust web frameworks and it has been the most ergonomic by far.

  • @ruffianeo3418
    @ruffianeo3418 ปีที่แล้ว +4

    The 2023 (re)-invention of global variables, with lots of code mutating it from everywhere and no where :)
    This was the "model" I used in the 1980s for my C programs. Now I know it was "reactive" not "spaghetti" :)

  • @zwillx3953
    @zwillx3953 ปีที่แล้ว +6

    That's some impressive coding while presenting , and great explanations along the way

  • @Baron-digit
    @Baron-digit 3 หลายเดือนก่อน

    Man, seeing how easy you walk through it and how well you can explain that.. I feel intimidated :D

  • @fionawashere1086
    @fionawashere1086 9 หลายเดือนก่อน +1

    fantastic presentation, thank you so much!
    I'm evaluating leptos for multiple future projects, and it looks very promising to me.

  • @cramhead
    @cramhead ปีที่แล้ว +3

    Such a fun demo and really interesting to see how it works under the covers

  • @DavidBudaghyan
    @DavidBudaghyan 7 หลายเดือนก่อน

    I am new to Rust, new to reactive systems and yet this video makes it so easy to understand the concepts and the inner workings. Thank you for the insightful video and clear explanation!

  • @henrikakesson4457
    @henrikakesson4457 2 ปีที่แล้ว +6

    Brilliant! Thanks. Really helped me understand the reactive system!!!

  • @v-for-victory
    @v-for-victory ปีที่แล้ว +2

    Greg, what a captivating introduction and thorough explanation! I was journeying through TH-cam in search of info on Leptos and serendipitously landed on your masterpiece. It was the guiding light I needed. Immense gratitude to you!

  • @neociber24
    @neociber24 ปีที่แล้ว +1

    Great explanation, really made me interested in dive SolidJS and Leptos internals

  • @MichaelMaraist
    @MichaelMaraist 9 หลายเดือนก่อน

    Just coming over from Svelte4 -> Svelte5 ; having to compare/contrast SolidJS style signals in both those frameworks, and seeing your talk just made EVERYTHING make so much more sense. Thank you.

  • @fionawashere1086
    @fionawashere1086 9 หลายเดือนก่อน +1

    31:29 This is exactly why Rust is so great. Even if it's a runtime borrow-check, it's still a borrow-check, and not a data race. ^^
    Same thing in 33:56.

  • @andredasilva6807
    @andredasilva6807 ปีที่แล้ว

    That was amazing. I didnt fully understand all the rust parts. But i feel like i finally get signals and effects. Phenomenal video. Thanks a lot

  • @Tigregalis
    @Tigregalis ปีที่แล้ว +2

    This is fantastic. Please make more videos! I'd love to see you go into the reactive scopes.

  • @pertuck
    @pertuck 2 ปีที่แล้ว +4

    This is really helpful. I've been wanting to try Leptos, but I was having difficulty grokking the signals and how the view! macro worked exactly.

  • @vvvvijjjj
    @vvvvijjjj ปีที่แล้ว

    Super cool. Needed to watch it a second time to code along. Thanks a ton !!!

  • @zactron1997
    @zactron1997 ปีที่แล้ว

    Thanks for this! This is a fantastic explanation on how Leptos works.

  • @verified_tinker1818
    @verified_tinker1818 2 ปีที่แล้ว +8

    Thanks for video. Super informative. Though the audio is a bit quiet. I'd appreciate it if you could make it louder in the future.
    I wonder how equivalent JS frameworks handle this. On one hand, they don't need to worry about things like RefCells and pointers. On the other, if they _do_ want to implement that (for performance), I imagine it'd be a lot harder, if not impossible. But I doubt they care. The performance gain is probably marginal for most UIs.

  • @joaodiasconde
    @joaodiasconde ปีที่แล้ว

    Amazing stuff, great rust skills and great simple design for a non-trivial problem/system

  • @dimashadziq6007
    @dimashadziq6007 ปีที่แล้ว

    Thank i m new to rust and its so hard for me to tackle wasm closure, your framework are really great and this vidio are plus plus. Now i understand better into borrow checker with your explanation

  • @zombiefacesupreme
    @zombiefacesupreme 2 ปีที่แล้ว +1

    Thank you for this content!! Super excited with what you're building here.

  • @doce3609
    @doce3609 ปีที่แล้ว

    This was really cool.
    Thank you for explaining this so beautifully.
    You should link these videos in the documentation somewhere as a reference maybe.

  • @samhanna7382
    @samhanna7382 2 ปีที่แล้ว +1

    its good that you are making content!

  • @MuteObserver
    @MuteObserver ปีที่แล้ว

    Thank-you, a lot of new info to connect up, going to be back to review

  • @AccordionMusicAndMore
    @AccordionMusicAndMore 6 หลายเดือนก่อน

    Great vid! Thanks! Keep them coming ;)

  • @bigmistqke
    @bigmistqke 2 ปีที่แล้ว +3

    Love this video. Reminds me of solid's 'introduction to reactivity' video. Very very cool to see it for rust/leptos.

    • @bigmistqke
      @bigmistqke 2 ปีที่แล้ว

      Actually made me understand the solid-video better, the whole subscription-context was a part i could never fully grasp. Very well explained!

  • @InDieTasten
    @InDieTasten ปีที่แล้ว +2

    Would've loved to see you detailing how this system works with effects with multiple code paths, that depend on different signals depending on some other signal, as it will also "discover" all the dependencies as they get relevant during the runtime. Really neat.
    In some cases, it could even be advantageous to remove entries from the hashmap again as they become irrelevant to the effect again, though most likely this kind of micro-management of subscriptions is probably overkill for the mostly straight-forward effects.

  • @jhvkgvb
    @jhvkgvb 2 ปีที่แล้ว +1

    Thanks for a great explanation! :)

  • @MakerPnP
    @MakerPnP 2 หลายเดือนก่อน

    Thanks for making the video.

  • @zahash1045
    @zahash1045 ปีที่แล้ว

    I may be wrong but isn’t this exactly how react hooks work?
    React maintains one giant array where all the state is maintained (don’t need to do because js is dynamically typed) and it returns the reference to read the state and a function to update the state

  • @alpaslaneldemir6904
    @alpaslaneldemir6904 2 ปีที่แล้ว +2

    Thanks Greg.

  • @JustAnotherLight
    @JustAnotherLight ปีที่แล้ว

    love this! thank you

  • @kirglow4639
    @kirglow4639 ปีที่แล้ว +2

    This is awesome. My concern is that these signals and effects don't ever seem to be cleaned up, so the innocent single leak in reality turns into a bigger leak as you add more and more of these signal values. Wondering what the approach is to clean those up when the app no longer needs them / references them. I've also built a reactive system but had to use reference counts everywhere for this reason

  • @paulycdong
    @paulycdong ปีที่แล้ว

    Perhaps I am a bit late to this great tutorial… on 2:22 , how did you spawn up this web server? And what versions of Leptos and Web sys did you use? I am trying to follow along but the imports seem not to be working… thanks!

  • @jrmoulton
    @jrmoulton ปีที่แล้ว

    This is such a great video

  • @burm4npgoget707
    @burm4npgoget707 หลายเดือนก่อน

    Just came back from a Frontend Sheffield Meetup and one of the speakers, an Amazon engineer Tom Johnson, said they were using Leptos in their Prime team for 3rd party devices.

  • @shadamethyst1258
    @shadamethyst1258 ปีที่แล้ว +3

    Very interesting!
    I am wondering, however, if signals (and their associated data stored in Runtime) in leptops ever get freed. I could see this becoming problematic for eg. a popup, where signals and effects are created whenever the popup appears, and won't be needed after the popup closes. Do those values in Runtime just sit there until a page reload?

    • @gbjxc
      @gbjxc  ปีที่แล้ว +7

      No this is just a simplified form of it - in reality they are tied to reactive scopes and disposed of appropriately when different parts of the UI and removed. So in that example, the signals would be disposed after the popup is closed.

  • @tobias3581
    @tobias3581 ปีที่แล้ว

    I’m definitely betting my e-commerce startup on Leptos

  • @paulholsters7932
    @paulholsters7932 ปีที่แล้ว +1

    Very nice. When there will be a rich ecosystem around this framework like a big UI library? Like the Primeng library for Angular? Is such a thing already being build?

  • @feepdake9610
    @feepdake9610 ปีที่แล้ว

    Hi, man. Great content. Very interesting, though hard to grasp in one pass.

  • @flylord42
    @flylord42 2 ปีที่แล้ว +3

    do you have the project in github?

  • @jorenboulanger4347
    @jorenboulanger4347 ปีที่แล้ว

    ❤ it really helped

  • @frantisek_heca
    @frantisek_heca 8 หลายเดือนก่อน

    How current is it in the context of Leptos versions, please? For example, the logic in this video would be mapped to which Leptos version?

  • @iippari7
    @iippari7 ปีที่แล้ว

    This was incredibly interesting, and your explanations were very clear :) One thing that stood out to me is the requirement that the initial call to an effect calls and registers the appropriate signals. If, for example, I had an effect that counted how many times it had run, and didn't call the getter of some signal A on the first run, but only on subsequent runs, could I fool the runtime into declaring the effect as having no dependencies (thus, never running) when in reality it uses the value signal A?

    • @gbjxc
      @gbjxc  ปีที่แล้ว

      I don't think this toy version actually does it (I'd have to look back) but in real reactive systems like this dependencies are dynamic, so they always only subscribed to the signals accessed on the previous run. You can manually say "track this signal without reading its value" if you want to, which is basically what you're describing I think... "Always run this effect if this signal changes."

  • @gabrielanghinoni4623
    @gabrielanghinoni4623 2 ปีที่แล้ว +1

    Nice video, great start! try to ajust the audio next one pls, its too low.

  • @brandonhunter3036
    @brandonhunter3036 ปีที่แล้ว

    Nice man!

  • @zenshade2000
    @zenshade2000 ปีที่แล้ว

    Does anyone know what that color theme is? I really like it a lot.

  • @feepdake9610
    @feepdake9610 ปีที่แล้ว +1

    Hi, Greg. Can you make a short video on how one can learn the js/wasm interoperability and how the whole machinery works down one level compared to current video. Maybe just a bunch of links, as you probably won't be interested in sharing deeper secrets you've learned and educating instead of spending time developing.

    • @gbjxc
      @gbjxc  ปีที่แล้ว +2

      Yeah! Are you thinking like a “How to build some basic stuff with Rust and wasm-bindgen” or “How does wasm-bindgen actually work?” If it’s “how to build some basic stuff” I went on Ryan Carniato’s stream a while ago and walked through this- if it’s “how does wasm-bindgen really work” then yeah but it’s over my head a little :-D

  • @nickbanderson
    @nickbanderson ปีที่แล้ว

    Beautiful

  • @zahash1045
    @zahash1045 ปีที่แล้ว

    Why not set the current running effect in the create effect method instead of run effect method.
    because you only need to figure out which effect depend on which signals only once and not every time the signal is run?

    • @SVVV97
      @SVVV97 ปีที่แล้ว

      Because in a real system you'd really want to newly figure the dependence out every single run: the basic idea is that you want to minimize how often effects are run at basically any cost.
      If you have have an effect that does something like `if some_signal() { do_something_expensive(signal_1()) } else { do_something_expensive(signal_2()) }` you wouldn't want to rerun the effect if `signal_2` changes while `some_signal` was `true`. Moreover this effect couldn't even subscribe to `signal_2` if `some_signal` started out as false.

  • @jimhrelb2135
    @jimhrelb2135 ปีที่แล้ว

    I got really distracted by the usage of Box::leak earlier in the video. I tried looking around and couldn’t find why we’re using it. Ideas?

    • @gbjxc
      @gbjxc  ปีที่แล้ว +3

      Box::leak() gives you a &'static T, which is very useful in particular cases where you want a lifetime with a static reference so that everything that holds it doesn't need to have a lifetime. In this case as it's called once ever, it's not really a leak per se, just a single allocation that doesn't get deallocated until the end of the program.

  • @GlobalYoung7
    @GlobalYoung7 2 ปีที่แล้ว

    thank you ❤🎉

  • @Wadu436
    @Wadu436 ปีที่แล้ว

    Could you make the runtime 'static with something like lazy_static! as well instead of a Box::leak?

    • @gbjxc
      @gbjxc  ปีที่แล้ว +1

      For sure! In the real library I do it with a thread-local, they’re just slightly more awkward to work with than a static reference so I took the simplest path here.

  • @TeoDumski
    @TeoDumski 11 หลายเดือนก่อน

    Could you provide code you created throughout this tutorial? It'd be so helpful to study your code without scrolling youtube video back and forth :p Great work, BTW, many thanks!

  • @theplanebrain
    @theplanebrain ปีที่แล้ว

    Is this all static?

  • @dominigon
    @dominigon ปีที่แล้ว

    Nice video, I hoped you would show conditions inside create_effect and how you unsubscribe first before resubscribing again as you explained in other video

  • @drsensor
    @drsensor ปีที่แล้ว

    Some people I know use Leptos with gtk-rs

  • @danvilela
    @danvilela ปีที่แล้ว +1

    Brooo why did you choose the leptospirosis name????

  • @user-qr4jf4tv2x
    @user-qr4jf4tv2x ปีที่แล้ว

    already got lost use leptos::{create_element};
    #[derive(Default)]
    struct Runtime{
    }
    fn main(){
    console_error_panic_hook::set_once();
    let body :HtmlElement=body().unwrap();
    let p =create_element("p");
    p.set_text_content(Some("OK"));
    }

    • @user-qr4jf4tv2x
      @user-qr4jf4tv2x ปีที่แล้ว

      |
      301 | pub struct HtmlElement {
      | ^^^^^^^^^^^ --
      help: add missing generic argument
      |
      11 | let body :HtmlElement=body().unwrap();
      | ++++
      error[E0425]: cannot find function `create_element` in this scope
      --> cache_front\src\main.rs:13:12
      |
      13 | let p =create_element("p");
      |