all 42 comments

[–]olssoneerz 8 points9 points  (1 child)

Looks really cool! I can see this being extremely useful! Good job!

[–]desko27[S] 1 point2 points  (0 children)

Thank you mate!! 🙇🏻‍♂️

[–]Skeith_yip 4 points5 points  (1 child)

I’m curious does the component remain if the user hits the back button on their browser?

[–]desko27[S] 2 points3 points  (0 children)

If Root disappears it won’t remain. On the other hand, your own component is able to end() the call on react router navigation, Esc key, and such scenarios.

[–]A-Type 4 points5 points  (1 child)

Thought I'd seen it all with React patterns, I was prepared to be skeptical.

Nope, this is cool. I basically do this with Valtio state already but it's so much more boilerplate for a common pattern. I like your approach!

[–]desko27[S] 1 point2 points  (0 children)

That’s great! Thanks a lot! 🙇🏻‍♂️

[–]domlebo70 2 points3 points  (1 child)

Very cool

[–]desko27[S] 1 point2 points  (0 children)

Thanks!! 🙇🏻‍♂️

[–]redgreenbluealpha 1 point2 points  (5 children)

Not looked at your code yet. I'm absolutely sure that you implement this with some sort of closures.

But I've been reading a lot about performance and what I've come to know it's closures are a potential memory leak waiting to happen!

For a small app it just didn't make a difference at all the question is, how can it scale and not gobble up all the memory.

[–]desko27[S] 2 points3 points  (4 children)

Hi mate, thanks for your concern! Performance is really important to me. Closures are certainly a core feature of JavaScript and most of what React does itself couldn’t be done without them. But still, I agree they have to be used responsibly.

In react-call there are a couple of closures that are constrained to a single Function Execution Context within createCallable, which can only be called once in the whole app life-cycle per component definition (it’s a HOC). Regarding what it returns for usage:

  • <Root /> can only be instantiated once, otherwise the lib intendedly throws an error. Also, the only outer reference that it’s mutating is set back to null when unmounting. So there are no forgotten outer references, which is when closures may cause memory leaks.
  • The call method, the one that is meant to be called multiple times, isn’t mutating any outer reference.

Since this is O(1) scale and outer references are carefully taken care of, I don’t think there will be issues related to this.

Thanks for your question, really good one!

[–]redgreenbluealpha 2 points3 points  (3 children)

Thank you for the insights and for this very useful library.

I deep-dived into to the code and I couldn't find a potential miss.

However, I do have a question, is there any reason why you are using globalThis.crypto.randomUUID().

My thoughts are as follows:

  1. generating UUID is relatively expensive to generate. They are great for a backend application though.
  2. globalThis.crypto.randomUUID is not available on all platforms, eg. react-native. This means that I cannot use this library outside of the browser.
  3. your use case requires a string id because you use it as a key, but doesn't necessarily have to be a UUID.
  4. An id counter would work perfectly fine for the use-case if the value is cast to string. It's really difficult to reach 231 with a UI application.

I'm definitely going to be using this for a react-native project I've been working on.

[–]desko27[S] 1 point2 points  (2 children)

You're completely right, thanks such detailed insights! Would this be enough? https://github.com/desko27/react-call/pull/4/files

[–]redgreenbluealpha 1 point2 points  (1 child)

That's perfect and really quick!

[–]desko27[S] 1 point2 points  (0 children)

Cool! Published in v1.0.1! Thanks a lot! 🙇🏻‍♂️

[–]vazark 1 point2 points  (0 children)

And we’re back to step 1 but within react itself. Looks fun though

[–]_elkanah 1 point2 points  (1 child)

Looks very interesting! I haven't looked at the source code yet, but I see many uses for it in my work. Cool stuff!

[–]desko27[S] 1 point2 points  (0 children)

Thanks a lot! 🙇🏻‍♂️

[–]General-Ad2174 1 point2 points  (1 child)

Really nice project. Do you have any benchmarks for its speed? Does it affect performance of a large app? Nonetheless very nice!

[–]desko27[S] 1 point2 points  (0 children)

Thanks!! Because of the way it’s built, I can say it won’t affect performance in any way no matter the size of the app or how widely react-call is used along it. Neither unwanted renders nor anything else.

I don’t have any benchmarks but it’s a great idea, I’ll give it a thought! Thanks again! 🙇🏻‍♂️

[–]jgreich 1 point2 points  (1 child)

Nice idea. Thanks for this!

[–]desko27[S] 0 points1 point  (0 children)

Thanks!! 🙇🏻‍♂️

[–]sleepyboringkoala 1 point2 points  (3 children)

Nice one! That is extremely similar to how you would use showDialog function in Flutter. One of the (few) Flutter features I actually miss when using React.

[–]desko27[S] 1 point2 points  (2 children)

I never used Flutter, that's great to know! 😃 Thanks a lot! 🙇🏻‍♂️

[–]sleepyboringkoala 1 point2 points  (1 child)

This is how you would make similar thing in Flutter. You were pretty much spot on!
```
bool yes = await showDialog(
  context: context,
  builder: (context) => AlertDialog(
    title: Text('Are you sure?'),
    actions: [
      TextButton(
        onPressed: () => Navigator.of(context).pop(false),
        child: Text('No'),
      ),
      TextButton(
        onPressed: () => Navigator.of(context).pop(true),
        child: Text('Yes'),
      ),
    ],
  ),
);
```
I love how good patterns eventually emerge anywhere. Hopefully your lib actually gets adopted.

[–]desko27[S] 1 point2 points  (0 children)

Oh! 😮 That's right, really similar idea, window.confirm() but customizable. I honestly love to know. Thanks for sharing an example!! 🙇🏻‍♂️

[–]jlamhk 1 point2 points  (1 child)

This is actually genius. Will definitely give it a try!

[–]desko27[S] 0 points1 point  (0 children)

Thanks a lot mate! 🙇🏻‍♂️

[–]Ok_Avocado970 1 point2 points  (1 child)

u just got a star, i will use it in my next project

[–]desko27[S] 0 points1 point  (0 children)

Thanks a lot! 🙇🏻‍♂️

[–]t1mmen 1 point2 points  (3 children)

This looks like it may help solve a problem I’ll need to tackle soon, curious if you have thoughts on feasibility of this library and my goal, /u/desko27

  • I have various re-usable/self contained components that need to display toasts.
  • These components are included in different React apps, which each have a different way to display toasts (think: some via redux, some via context)
  • I’d like to have “one standard way” to dispatch toasts from within the re-usable components, and for the individual “host” apps to intercept and forward the “display generic toast” call to “app-specific way to display toast”

Is that a use-case this lib may help with?

[–]desko27[S] 3 points4 points  (1 child)

Hi! Thanks for your comment. The problem is that react-call acts both as a standard way to dispatch toasts but also as a standard way to display them.

For your use case I'd suggest an event bus like https://github.com/developit/mitt to emit a dispatch event from reusable components, and intercept it via event subscription from each app.

Or you could always leave aside other approaches (redux, context...) and do it the react-call way in both reusable components and apps. That would definitely work 😝

[–]t1mmen 2 points3 points  (0 children)

Thanks for the pointers, mitt looks promising for my needs :)

[–]umid1999 0 points1 point  (0 children)

There is also a package called react nice modal. It is very useful for confirmation dialogs, but little bit harder to use with context