Hey, welcome to React Round Up, the podcast where we keep you updated
on all things React related. This show is sponsored by Raygun and produced by
Top and Doves and Onvoid. Top and Doves is where we create top and
dowves, so we get top and pay and recognition while working on interesting problems
and making meaningful community contributions. An Onvoid offers remote design and software development services
on a task basis, so clients only pay after tasks are delivered and approved.
In today's episode, we have a very special guest, so we have
Dean Radcliffe and we're going to be talking about his library. So Dean created
a universe of libraries actually called our ex facts, and for those of you
that are familiar with our exgs, you're gonna probably already get the reference of
the RX in front. So it's definitely a library that solves problems with reactivity
and it is framework agnostics, so right now it works on Angular React and
it probably works on other frameworks too, So we're gonna talk a bit about
that and how this might be useful to improve the reactivity of your projects.
By the way, my name is Lucas Paganini. If you don't already know
that I'm one of the hosts here in the show. Enjoining me in today's
episode is Chris Ruin, Hi, everybody, Peter Osa, Hi everyone,
and the one and only Charles Maxwood. Hey folks. All right, so
yeah, Dean, let's get into it, man. So why don't we
start with introduction of give me your elevator, pitch off our active effects,
and then we can start diving deeper into the subject from there. Does that
work? Yeah? Sounds good? Okay, okay, So first I'll introduce
myself. I'm Dean Radcliffe. I say I'm a developer of many years experience
covering Java, dot Net, Ruby, JavaScript, and typeescript, focused on
full stack development with Typescript at a large insurance company. LUCA is another play
on r X from RX effects is It's like it's your prescription for a effects
execution. Ooh nice, nice, there you go. I live in the
Chicago area with my wife and kids in first and third grade, and my
interests include staying active, mental health, and playing a four string guitar of
my own design. Our ex effect Okay, so what the heck is it?
Why did I make it? So let's establish the context for OURXFS writing
ACNC code is hard and error prone, and the recent advice from the React
community around use effect and whether you should or not is confusing. We end
up having to code for ACNC edge cases all the time, like concurrency control,
cancelation, progressive results, but we tend to treat them as edge cases,
so we either miss building them in the first place, or the code
that we write to handle all the edge cases crowds out the happy path.
So what if you could have a library usable in or out of any React
component which provided solutions so the most common ninety nine percent of ACNC use cases
you'll encounter without you having to declare a single new variable or write a single
additional then or a weight. What if you had really nice composition of async
effects that kind of covered the whole gamut like RxJS has. If you had
that, you could also have full separation between your view logic and your effect
logic. There's been talk on the show about in episode two forty on code
based patterns, how some people like to take the style component stuff out of
their file so that it's focused on rendering, and then some of you also
take some of the ACYNC stuff out of your file and put it into a
custom hook so that you have, you know, a separation of concerns.
So I'm a big fan of separation of concerns. And if you can move
the effect stuff out and I mean out, not even into a custom hook,
but all the way outside of React stuff, then you could test it
without using REAC testing tools, and tests could run fast, et cetera.
So contextually historically to think about like some libraries that have stilled this role over
time. In the early days, does anyone remember the ACENC library. It
had methods like waterfall to like sequentially do ACENC execution or I think parallel very
early days of no right call back hell. We don't like callback hell.
Right before Promises, there were several attempts to solve call back hell, and
the ACNC library was one of them. Now people don't know this, but
prior to Promises, Microsoft created the observable, the foundation of our XGS and
something that's soon to be landing in your browsers. So our XJS happened about
twelve years ago, and now I think of our x effects. At least
for my personal evolution, it's the third generation of like ACYNC handling tools,
that is simpler than our XJS, but it's built on our XJS and it
solves a bunch of React problems, and it's just kind of become my go
to pattern for anything that is not already covered by hooks like us query of
Apollo or like tanstat query. So those data fetching ACYNC things, there's really
mature libraries for that. So our x effects isn't to replace those, it's
to supplement those use cases like authentication, animation, playing sounds, modal dialogues.
Anytime you're initiating an async interaction with the user that is not already covered
by one of those hooks. RX effects can be your your thing. I'll
pause, there are there any question? There is that clear? I really
like the So basically the idea is anything that you find yourself struggling to do
asynchronous lead because it's not well covered by the the native group hooks that React
exposes, this is where our x facts would shine, right, So basically
that's that's when you would lean towards our xifacts versus just to use a factor
or something like that. I like that. I would like to get a
few more examples on that and start maybe even going into some of the use
cases where you saw yourself using our ax effects more and that maybe you hear
that people are using it more for those use cases as you briefly mention some
of them. But I think it would be nice if we could do a
little bit deeper on that. Sure. Sure, And there's like three lenses
to view like the kinds of problems it solves, because that's clearly what it's
all about. Like, does have have what I call what we call d
X problems developer experience problems? Yeah, you know, code maintenance and running
tests and that kind of stuff. That's one lens that I found. It
helps ux what a user expects when an async operation occurs. They have a
whole host of needs that like, for example, they want to know they
want to see an activity indicator. They want to know is this doing what
I asked? So with our XFX, you can get a really nice activity
indicator without having to declare a separate use state for like is loading a set
is loading? So I recently went into a code base where there was an
issue with when a user aborted an authentication by by canceling out of it,
the spinner was still spinning because the set is loading variable was still true.
But imagine that you can just wrap any ACYNC function in something in like a
higher order function that would give you this activity indicator for free. That's something
that that RX effects does. I mean, so users have expectations, and
it was really when I was trying to satisfy the needs of the most picky
users. And by that I mean my mother, who you know will push
a button and be like, is this thing working that sounds like my mother?
Yeah? Pretty much, pretty much. So I compile the little list
of things that annoy my mother, and RX effects addresses them. If it
doesn't show whether it's working or not. If it doesn't show something like percent
complete, like is it working well enough or fast enough, that's also valuable
information, she'll change her mind it's taking too long, especially if you show
her percent complete and installed at one or stalled at ninety nine for thirty seconds
like so many things, so she'll want to cancel that or cancel that when
out changes right or something in your apps of cancelation is important for users and
for a code bases and concurrency, because she might smash the button multiple times
if she thinks it's not doing something and errors fully recover. So I don't
ever want to hit an error boundary. I don't ever want my users to
hit an error boundary and react because like things are like really broken for them.
So OURX effects is like having a circuit breaker panel where you add in
async effects over time, as you do in your code base, you send
analytics events, you do this, you do that, And what can happen
to apps over time is they destabilize because one of these effects acts up and
now you've hit an error boundary or an uncaught uncaught rejection. So ourx effects
has like got each of your effects behind like a circuit breaker. So if
you or any other developer fails to handle an exception, the scope of that
exception or error is limited to the thing that caused it. And from a
user's experience, you want to be able to gracefully recover, and so you
want to be able to set timeouts on things very easily. I was on
a site, an insurance site, and they had just started asking they popped
up a new modal dialogue that they didn't have before. I used to log
in and go right to this homepage. They popped up a modal dialogue that
said, are you using English or Spanish? Now? Never mind that they
probably should have been detecting that from the headers of my browser. But they
pop up this modal dialogue in a light box, and I picked the button
and it doesn't dismiss the modal modal. The modal doesn't time out. Like
nobody thought at the beginning of this modal, how long is it worth the
user on this screen that they can't get off of? Well, obviously they
thought that the user would just make a choice in it be over right,
But it should be a design consideration for anything that takes time. What's a
reasonable amount of time? So timeouts I think are important in just about any
ACYC effect execution. So I've actually written a sublibrary in this universe of libraries
called RX effects Perception where you can use constants like deep breath that's about four
thousand milliseconds. Should it time out after a deep breath? Should it time
out after a blink of an eye that's about one hundred and fifty milliseconds?
You know, like you know, you should be able to choose user centered
values for timeouts, and you should be able to plug them into your code,
like I said, without complicating the happy path. It should be like
progressive enhancement that doesn't like cause you to go back to the drawing board and
rewrite everything from scratch. So what I'm kind of wondering because you're you're talking
about some of these different examples, but in practice, if I'm going to
put this into my code, you know, does it look or feel like
promises? I mean under the hood it may work completely different. I don't
know about that, but you know, or does it look or feel more
like observables and r x jas Okay, you know, could it be classified
as observables or classified as promises or classified as something else? Or is this
a completely different way of doing things? Well, no, it's it's it's
not that different. And if people are curious to see one of these things
in action, like right away, you can go to code sandbox and look
for an RX affects template and it'll show you an ACYNC counter. So the
old counter example from React and every other framework has an incrementing counter. So
if that if that counter takes some time, so you can take a look
get at the code right away. But basically, Charles, imagine you have
an ACYNC function that returns either a promise or an observable. It doesn't matter.
Effects isn't going to force you into observables. If you have promise returning
functions, you can use those. And so imagine a higher order function that
you pass your promise returning function into, and we'll use the simplest one called
create effect. Okay, So you pass your promise returning function into create effect,
and what you get back is a function that you can call to begin
that effect, but already concurrency controlled. So if you said create queuing effect,
then multiple calls to that function that will and queue each promise after the
other, and you also have on that return value. It's a function you
can call. The return value from create effect is a function you can call,
but it also has a lot of mesaids and properties on it, including
is active, which you can subscribe to to find out is that function still
executing and what else. I mean, there's a number of things on there.
I don't want to overwhelm you, but basically, it's a higher order
function that you know, just lets you call that original function, but have
access to things like activity and cancelation in a uniform way. So now promises
are not cancelable like by default. So if you want to do like a
cancelable ajax, you return an observable of that ajax, and observables are cancelable.
So if cancelation is important, that's one reason to use this higher order
function around your your function. Because what comes back from create effect or creates
service is something that has a dot canceled current method on it. And so
you know you're not declaring new state variables for like is canceled or whatever you
have like programmatic access. So yeah, the original functions charles that you have
returning promises, those still exist and they don't have to know anything about our
x effects. It's it's our x effects that takes that function and provides these
convenience wrappers on top of it. Okay, okay, So so expanding a
little bit more on that. So, first, I know that the library
is a framework agnostics, So I don't expect hooks, for example, to
be first class, first class citizens for all the distributions of the library,
just because if you were on an angular context that would that would make no
sense. But I also understand that at least at this moment, most of
the developers that are using and finding a huge amount a huge amount of value
from our xfacts are within the reactive community, at least at this moment.
So let's let me grasp a little bit better. And also let's try to
give the audience which is just listening to us. Unfortunately most of them won't
be watching us but on YouTube or something like that. But do you have
a hooks version for each of those of those packages of the RX universe.
Yes, absolutely, absolutely so. I took great inspiration from the x state
library that kind of has its own universe of libraries for defining state machines and
then having hooks to tie your state machines into your components. So it's exactly
like that in the sense that you're this this higher order function what we call
a service or an effect, depending on whether it's keeping track of state.
I also want to talk about state management and how how the pub sub nature
of our X effects can simplify state inside of your React applications. But yeah,
the hook there are hooks for just using it in a very familiar hook
interface for React developers. Nice, nice, okay, and in other contexts
just for completion. So if the person were to use your library within an
Angular cobase, for example, then what would be the the interface to interact
with that. Would it be something close to observables with the typeable classes with
your functions, or how does it look like. So there's a very lightweight
version of this higher order component thing, which I just call an effect.
It just applies concurrency control and cancelation and activity tracking to any async function.
Then, but I think the most useful place that people will want to start
is the service, which is both an effect that's concurrency controlled and all those
things, but also keeps track of state. So now if your service keeps
track of state, so for example, you're beginning an O off flow and
the state that you want to keep track of is the access token that came
back. Well, let me see that was not something you would paint to
the UI. Let's say that you're making Let's say you're in an Apollo application
and so your server has all its graph QL stuff tidied up, but you
want to make a one off rest call to get a random cat gift from
a service. Okay, so now you need to get that random cat gift
into the UI, and Angular you can acync pipe the state of that service
right into your Angular template. So because the state is reactive slash observable itself.
In a React context, you can consume it with hooks. In an
Angular context, you can consume it with an ACNC pipe. And those are
those are two ways you can you can get at it. Okay, okay.
When you mean acinc pipe, you mean you mean a native ACNC pipe,
which would be asynchronous function generator, so you would have something like a
for a sync cost off and then you pipe through the stream of data using
native acinc generators or would it be uh library specific implementations such as what our
x jazz has with dot pipe. Oh no, I didn't mean either of
those, and I might have gotten the terminology wrong. But in the Angular
templating language, you can oh gotcha acinc pipe from from Angular the native pipe
the Angular exposes Okay, okay, then yes, yes, that's what I'm
at mm interesting, interesting, Okay. And let's say that I wanted to
extend something that your library does with some other observables directly from our ex jess
because I imagine and that that's an assumption, but you can correct me from
that internally. The universe of libraries from rxffcts is built using r xgs right,
Yes, yes, Do I have the possibility at any point to directly
deal with RXGS observable classes, Yes, you totally do. And I think
one of the differences with kind of RX effects to like you could say that
it's opinionated because it focuses on a subset that seems to deliver the most bang
for the book for you know, a shorter learning curve. So the place
that you would most likely to start using an observable in RX effects is as
a return value from a function. You used to return a promise, Now
you return an observable. Why would you do that one? Because you want
it to be cancelable. Okay, every observable since twenty eleven when they came
up with it, it is cancelable. Promises. Are still working on that
with the board controllers, and it's not every promise that can take in a
board controller, so and you also need a reference to that a board controller
around to cancel it. So it's it's the DX of canceling promises is quite
awkward, but the DX developer experience for canceling observables is super easy. It's
you know, how I use effect function? You have like the code it
runs and then you return a cleanup function. Yeah, they lifted that right
off of observables. That's how observables do it. You return a cleanup function.
So that's what allows you to cancel from the outside. In other words,
you don't have to pass a signal in or a board controller. You
can just cancel it because you don't need any other reference to cancel it.
I think I got off track there a little bit. Where would you use
observables? So now our x JS has some very cool what they call operators,
and there's a there's an example that I built of a you know,
when you go to the self checkout grocery line, there's a there's a card
reader, and you're supposed to click pay now on the user interface before you
stick your card in. But sometimes I forget and I stick the card in,
and I'm like, shouldn't you just figure it out? And it's like,
no, I got to click the pay now. But so it turns
out it doesn't matter what order you uh click the pay now and and insert
the credit card. So our ex has an operator called ZIP two streams or
observables and tell you when each one of them the value, so give you
pairs of values. So in this case, if you had a service for
an RX effects service score when the user hits the pay now button, and
an rx effects service for when the credit card is put in, you can
use that zip operator from our x JS to like get the combined you know,
the moment that they that they both happen. I suppose you could also
use like all. But but yeah, I mean so there is complete interoft.
I haven't cut off the option to use any advanced RXGS feature. I've
just made it so that you generally don't have to. And when you are
using an observable, you're using it as a return value from a function,
so you're not using you're not usually calling dot subscribe on an observable, whereas
almost every RXGS example has you defining an observable and calling dot subscribe on it.
And there's a lot of confusion in that community of whether you should call
dot subscribe or whether you should tap a you know, function into it so
that it runs for each value. So by using the observable as a return
value in our x effects, your side stepping that that issue entirely. Okay,
I really like that. I like that you're providing a simplified approach to
some of the user experienced features that people can get with our XGS, while
still allowing people to tap into our exgs full flexibility to create other stuff.
This is really nice, really nice. Yeah. The challenge is the learning
curve of our XGS is really steep, and there's four incredibly useful operators.
Out of maybe one hundred that they have, there are four that distinguish themselves
far above the others, And unfortunately they have some of the most confusing names.
But they deal with concurrency. You know what I'm talking about, don't
you? Merge men? Yeah? Map? What what the heck? I
can? You know? I can never remember it? So those concurrency modes,
if you don't mind, I'm going to try to do a little demo
here with audio so you can hear what these concurrency modes are, so that
you can imagine yourself using them in your application. Can I can I try
that? Yeah, let's give it a shot. All right. So this
is an application that is going to read a list of names, and it's
going to have a race condition because it's not going to be done reading the
first name by the time the second name came in. You know, the
second name is asked to do that. So let's see if we can hear
a couple of names in this application. Okay, let's try this one more.
An application that's gonna read names with a race condition where one name is
not done being spoken by the time the second one against? Is that better?
Can I tend to value? Yeah? I could hear that that's a
race condition there, So let's let's so so this happens all the time that
you that you have race conditions and you need to solve them. So what
those four r x JS operators I was referring to do is they allow you
basically all of the fundamental ways you can handle a race condition. Now how
do I know that they're all the fundamental ways? Well, there's there's a
couple of things you can do. If if an effect is going and a
new effect comes in, you can either start it right away on the other
one or not started at all. For something like a form submit, if
someone tries to submit a form twice, you don't want to start that next
form submission. And other times you want to Q things like for this name
solution, quing might be the nice solution, And other times you want to
switch from the one that was executing. You want to cancel that and start
a new one. So these four RxJS operators with their funny names, are
accessible under more friendly names in the RX effects landscape. So I'm gonna I've
called what this mode immediate mode, which had the race condition. It starts
the new effect immediately. The next mode is going to be called simply quing.
So I'm going to run the same function. Right. Remember you just
you have a function that plays a name, your core thing. You pass
it into one of these RX effects higher order functions, and now you have
a concurrency control version of that. So here's the queuing version. Lucas Paganini,
Charles Na's word. Okay, and you can see I didn't. I'm
not showing you the code, but you're hearing it. I didn't have to
change any of the any of the playing function, right, And there's no
additional lines of code. You're just saying instead of create effect, you're saying
create queuing effects. So another one would be create blocking effect. So whose
name are you going to hear when we say block the second one? Lucas
Paganini, Sorry, Charles, you were blocked, right, So sometimes you
want to resign. Yeah, I know a thing or two about that.
Wow, that was good. So the blocking mode. Another one is the
switching mode, And there are concrete use cases in development for all of these.
So now we're going to start doing one and then we're going to switch
to the other one. Loom charleson ax work. You see, you only
got the start off and then you canceled it, and then you went to
the next name, and then as I did my investigation, there's there's a
fifth one which is not in RxJS, and it's not the most useful,
but it's useful in one case where you want the second request to simply shut
off the first and not begin anything. That's called toddling loop. Uh okay,
just shut down. So being able to choose which currency strategy programmatically without
changing any of your code is just very powerful. Because you're building a user
interface, you might just want to try, like, which which is the
best Yes, which is the best concurrency strategy for this? So for example,
when I get new emails, a bell rings. Okay, so two
bells ring at the same time. Their volume levels can add up to too
high for your speaker to play, and it can get all long. So
you probably don't want to run the bells in immediate mode. And if I
get five emails at once, you probably don't want to run them in queuing
mode either, so that I hear, you know, five consecutor dings over
and over. So maybe for that one you want to use blocking. It's
already ringing. So a new email comes in, don't worry about it.
It's already ringing. You don't need to notify them again. Or you might.
Yeah, you don't want to use switching mode, where it begins a
ding for the first email and every new email ding ding ding ding dinging meaning
ding, But maybe you do. I don't know. It really depends on
the app. So I think that's the mode my kids operate in. Dad,
Dad, Dad Dad. Well, my first analogy for this, Charles
was if you're making a sandwich at the stove. Your kid wants a grilled
cheese sandwich and you're cooking the grilled cheese sandwich and then they're like, Dad,
I want chicken nuggets. Uh huh. These are the five ways you
can respond. So these are universal. This is not just cold, this
is like any time. So what can you do? You can just start
a new pan and start making the chicken nuggets at the same time. That's
immediatem You can say, okay, but I got to finish this grilled cheese.
I'll start your chicken nuggets after this. That's queuing. You can say
I'm making your grilled cheese. No dice, you're having grilled cheese. That's
my default, by the way, very sensible to be blocking. You only
have so much concurrency you can do. And then chain is like, oh
okay, let's wrap up the grilled cheese and tinfoil and get your chicken nuggets
going and toggling. This is the funniest one. I'm making a grilled cheese
and my kid goes, can I have chicken nuggets instead? I just stopped
making the grilled cheese and throw my hands and be like, pick your own
damn lunch, which I usually don't do, but in any events, my
kids are a teenager, so I have done that. Oh good, can't
wait to get there myself. So I really like the idea of just the
simple renaming of things in our ex jass. It sounds so stupid saying it
all loud, but a lot of what they need is just renaming some of
their operators, because you're right, merge map concat map just okay. I
find myself opening up the r x g S docs more than I should,
so they definitely could simplify some of the namings there. I'd like to know
how are they called in rx effects? So for example, this uh serialization
of events, which I believe is done with concat map if I'm if I'm
correct, how is that called in the r x effects universe? Queuing?
Good? Okay, that's a great example of how things could be simpler.
All right, yeah, and and uh there you know by the way.
Uh. One solution to the complexity is to bear down and learn it.
Another one is to use all x effects and a third one is to go
back and contribute to the RxJS docs. They're actively soliciting soliciting that and in
uh it was episode twenty two on your show that you had the RxJS team
on and they're like, yeah, we really care about docs. So like
this is not to like, you know, uh say that that it can't
improve in that in that direction, or that it hasn't like it is improving,
but it certainly feels simpler for me when I'm explaining this to Junior Dad's
on my team. You know, to say queuing, blocking, switching immediate.
It just requires no explanation. And it also doesn't require using like dot
pipe and pulling in one of these operators by name. It's just usually really
create changing. You know, is it create effect, does it create queuing
effect, does it creates uh, switching effect? You're just changing the name
of the higher order function. So that's maybe a little more like you know,
low dash and underscore have like specifically named functions, whereas in rx JS
you have this this piping style. It gets the job done, It solves
the concurrency issues. It was the inspiration clearly for for what I have.
But but it's it's not It's not a one liner. It does introduce another
import. It does introduce another line in the pipe, which is not much.
But you know, it's a one line change to go create effect,
to create queuing effect, and if it solves your problem, well then that's
a one pointer in your sprint, not a five pointer. And especially for
those in the React universe, this is only going to be the simplest way
to introduce our xgs into the context stuff React. Because recent episode that we
had and we were talking about how we approach reactivity. We we don't see
people using our xgs within React just because uh, it doesn't play well with
the universe of hooks, right, But with this then now you now you
can. So this exposes all the power of our xgs within the familiarity that
React developers expect of two with the React universe. So I think that anyone
that is using React and wants to add those reactivity features, this is thus
far I haven't heard of a better way to a better library that deals with
such issues. Wow, that's that's great to hear, and I'll mention at
like, using just plain use effect you can get two out of these five
modes pretty easily. You can get immediate mode. So imagine a component that
takes a name prop and you want it to speak a name. When that
name changes, you can envision use effect name dependency call this function that speaks
the name. Right, so you can get immediate mode, and if the
prop changes rapidly, you'll hear overlap with the names. Okay, but sometimes
you want, you know, things to run concurrently, so it's just one
of the five valid modes. Also, because you can return that clean up
function from use effect, you can shut down and you know, cancel the
first one and begin the second one. So you have two of those options.
But but then if you're going to be queuing them, for example,
you're you're adding new variables, and you know, as a code reviewer,
I can't imagine you know, a single form that you know, somebody's queuing
implementation would take. There'd probably be a bunch of different developers would do a
bunch of different styles, you know. But with with RX effects, if
you want to switch to queuing, it's a one liner and it's the same
one liner no matter where you do it in the project. So so then
you're you're you're you're safe. You know, it's simpler to read and write
and debugs. And this this actually brings me to like one of the first
use effect cases that I saw where I just became absolutely convinced that we need
to move effects out of the component tree. We need react to react to
our effects, we don't need our effects to react to react. And and
it was it was a stopwatch published by Kent See Dobs about three years ago
that had and is running state field and a stop button to flip that is
running to false. And it had a counter that as it was running,
it would run. And what he noticed was that there were when you sometimes
only once in a while, maybe once in five to ten times, you'd
stop the Stopwatch. And I'm wondering if the smiling means that some of you
have seen this before, But you'd stop the Stopwatch and it would tick one
more time, not every time. How the heck is a developer to figure
this out? And he made a call for solutions, and one and I
think the most widely accepted solution was defensive coding. Basically, change it to
use reducer and only update tick uh is running still true? So just basically
like when a tick comes in, make sure that you're still running before you
update the display of what that of what that tick is. But that doesn't
actually prevent the tick from happening, does it. It just prevents you from
seeing the tick. And that just got under my skin. I said,
this is not a solution, and so like, what is the problem.
Well, the problem is that it takes an extra react render cycle actually call
your stop your your you know. So imagine you have a use effect that
does a set interval and then a clean up function that does a clear interval.
And then you have a state field that's a dependency to control that interval
well from the moment that the stop button calls an event handler that changes the
state on that to the moment that your effect get canceled. It's not instantaneous
like, so you're not actually talking directly to your effect. You're talking to
React, which then talks to your effect. And we already know that like
React can and will change its timing. You know, it's it's allowed to
optimize and batch your set state calls, and it's allowed to do all kinds
of things. But the end result is that your effect is dependent on when
React update state. And I just said, you know, I've worked in
backbone before, and you know I worked yeah, yeah, places, I
have good memories of Backbone. But yeah, there are more powerful tools.
Now, there's more powerful tools. But the fact that it was very event
oriented and you could like react to an event right away as opposed to like
reacting to a state change. So I basically like am now skeptical of just
about any use effect that does async stuff because you know, you can just
ask, like, when React changes a major version and potentially re optimizes its
stuff, are you going to have maybe more condissions like the stopwatch that continues
to tick. Are you going to have more? Are you going to have
less? Can you can you really vouch as a developer for like, you
know, you've controlled for all those future possibilities. Well, as long as
you're effect execution and cancelation has to go through React, you can't. You
can't vouch for that. You take it out of React, you have something
that can literally just just stop the effect, no more tips, like right
away. So I think we should want that. I think we should want
to get that control back. It's nice to use what React gives you.
It's nice that it's not an additional library install. It's nice that's not an
additional learning curve, and there's tons of examples. It's nice that co pilot
can spit out use effect code at a at a you know, breakneck speed.
But it's not nice that you don't, you know, you give up
some of your ownership of when things execute, when when timing matters. You
want to keep that control. So I guess we're kind of getting toward the
end of our available time, you know, and still do kind of the
self promo picks. Whatever we wind up doing at the end of the show.
But I'm curious as we look at this and go, okay, it
sounds like there are some areas where this makes a lot more sense than use
effect or you know, trying to pull in our XJS or something like that.
So so how do I get this in my app? Yeah? Cool,
good question, good place to start. Like I said, if you
want to see some functioning examples that pull it into React, look for an
rx FX template in a code sandbox, or search for any number of the
dozens of examples there. But if you're ready to proceed, you do an
NPM install of at sign r x FX slash. I suggest people start with
service. It's an effect container and a state container, and then you take
your function that you want to concurrency control for example, and you call create
service. You give it a name, and then you pass your function.
The name is useful because underneath r x effects is an event bus and you
can like spit out log messages that have the name like you know, started,
completed next all those values. So you give it a name, and
you give it your function uh, and then you uh and then you take
the return value from create service and you can call it like a higher order
function like just as as the original function and the typescript types you know,
transfer between. Or you can call dot request, which is my preferred way
of of interfacing with it, because it's clear that now it's an object with
a lot of fields and properties rather than just a function. But you can
you can call it like a function, so it's really that import then arex
effectsify that's hard to say, pass pass your function into the higher order function,
create service or create effect, and then call methods on the thing that
came back, and that gives you your concurrency control. Uh, if you're
just ringing a bell, you don't don't really need to get state variables back
into React. You just need to ring the bell in a concurrency controlled and
cancelable fashion. But since most effects deal with state and remembering state, you
can use the used service hook from the at RX effects slash React package and
then that'll give you a reactive value of the state. So your counter,
for example, keeps track of its state, and so uh you oh,
you can. You can pass a reducer by the way, for the create
service call it's the name, it's the function, and then it's a reducer
to update that state. On any life cycle event like when a request happens,
when a response happens, when it's canceled, you can like you know,
massage that state with the reducer and so it's pretty simple as a drop
in that that can work for one component. And I'm going to mention signals
if you're interested in signals. One of the reasons people are interested in signals
is that you can have two components that import a third thing and they can
talk to each other. Right, one can update the signal and the other
thing can consume from the signal, and they can update each other without there
being a react context that they all participate in, and without passing getters and
setter functions around, so that RX effects service or the RX effects bus,
which is a lower level event bust those you can you can you can communicate
between components without prop drilling your setters and without doing context. By each component
having a reference to the service. One can make requests of the service,
one can consume the responses of the service, and and yeah, a lot
less prop drilling that way. That was Yeah, that was a lot man,
crazy, how much content there is with regards to reactivity and how much
of a pain point it is to to a lot of developers that just haven't
found an easy way to introduce them to introduce this into their their projects,
so they end up doing what you mentioned that that can't see dots I did
for for a very long time, which is just having another variable to track
if the request is spending or not. I think we we all did that
in a situation or another. So yeah, super interesting content and we all
feel bad about it too. Yeah, yeah, definitely, especially when it
doesn't work. It doesn't work. Yeah, so we we do got to
start wrapping up just because we're approaching the end of our of our time available
unfortunately. But I'd like to ask you, Dean, is there anything in
particular that you feel that needs to be mentioned that we haven't covered yet.
There's like critical for us to really close this subject, or should we just
start wrapping up. I'll say that testing goes very nicely when they're externalized premire
React components. And I'll also say that in one piece of code that I
cleaned up recently, there was a lot of a lot of the code around
a relatively simple asinc operation had to do with console logging statements of when something
occurred and and try catch to handle exceptions, and so our XFX has opinions
about both of those. You can log every event from a service. All
services participate on an event bus, and you can just spit out every event
that goes on on that event bus and boom. You're not writing console log
statements for like service return to value you know, or async function had an
error, and you're not writing try catch either, because the service basically turns
errors that might crash your program into just events on the event bus with the
slash error suffix. So yeah, error handling and spitting out console logs not
one of the more like glamorous or a sinky things, but certainly something you
can do with it that makes it easier. I've used it, by the
way, to understand h understand code bases. I've used event bus logging rather
to understand code bases. And the three kind of layers of RX effects is
first I developed an event bus. Then I created a service layer that can
a you know, keep track of state and do concurrency control. And then
lastly I created the reduced the minimal interface create effect, which does away with
naming of things and does away with having a reducer so those are your three
kind of like entry points. I recommend RX effects Service as like the main
entry point because it's like the all batteries included version, and if you want
to further customize what goes on, you can look at the r effects bust
library and write listeners exactly exactly as you want them and address some edge cases
there. I'll also say that the library is pretty mature in that it started
development like four years ago. It became very type scriptified about two years ago,
so it's very typescript friendly, and there just hasn't been a lot of
need to change the interface to it in the last year or two. So
there might be bells and whistles. There's always improvements and especially documentation that can
be added, but it's pretty complete, and the best way to communicate with
me about it is probably in GitHub discussions and issues on the repo, which
we'll put in the show notes right. And also, I don't have a
ton of time. Strangely, I'm promoting it because I think it should be,
but I don't know how much time I'll have to like answer questions and
do like full community around this. So if anyone's interested in kind of being
an active collaborator maintain around this. I welcome you with open arms. Awesome,
awesome, and yeah, I think you touched on a great subject.
We indeed haven't talked much about testing, so it's good that they mentioned this
at the end. All right, so first off, let's do some promos.
But I I'm already gonna say that Dean, this has been great.
Thank you so much for joining the episode. I'm really impressed with the fact
that you did all this preparation for the show. I highly appreciate that.
So yeah, I definitely definitely appreciate all the effort that you put into bringing
valuable content for the audience, and I hope that can repay all all that
effort in a way that is going to be interesting to use. So so
what would you like to promote, Like, do you want people to consume
your content? Follow you on social media? What could people do to help
you out? I would say, for now, it's it's any interaction on
GitHub that's starring the repo, that's adding things to discussions and issues. And
I am on Twitter at Dean dev Dad. Sorry, that's x Dean dev
Dad, and I can include the socials for everybody. But yeah, I'm
I'm not. I'm not. Well, we'll see if I get more engagement,
maybe I'll be on there more. Okay, all right, definitely gonna
start a repository. I'm gonna send a link to the repulse Storty here in
the in the comments, So all of you that are watching this live,
make sure to go into this repository and give it a start. It is
definitely deserves So yeah, I appreciate that. The So on my end,
I'm just gonna promote on Void. So it's U N V O I D.
So the inverse of Void, and basically what it does differently from every
other company that provides outsourcing services and stuff augmentation services is that with Onvoid,
you don't pay by the hour, you pay by deliverables. So they work
on a sprint basis, and for each sprint, tasks are determined and they
are estimated. So for each task we're gonna have estimates of points and the
clients only pay after the tests are delivered and approved. So if it's software
development, that would mean a PR that not only was open, but approved,
and maybe even after it is merged into the co base. That's only
then that it becomes buildable, So it is the safest way for companies to
outsource their design and software development teams and expand their human resources in a way
in which they're gonna still be able to track how much value those extra professionals
are bringing to the table, and not just how many hours they have consumed
in a given period. So, if any of you listening to this is
interested in that kind of service or know somebody that could be interested, it
is un void dot com on void, so yeah, you can just go
there and click on a button to schedule a meeting with one of Onvoid's representatives.
So, yeah, Peter Chris, you two were awfully quiet in this
episode. So I'm hoping that we can change this now. So let's yes,
Yes, that's true. Yeah, that required because I'm quite linking a
lot to the concept I'm adopting, right, So I'm actually quite enjoying it.
It doesn't kind of paying attention. Nice. Nice, Yes, So
let's start with you, Peter, So what would you like to promote?
Yeah, today, I just want to piss the with the getsbookle for our
ex effects today. Right, So I was looking to it and it's kind
of alsome, kind of give explanation on what it's about. I think that's
what I want to do today. Double link on the chart. Yeah,
the gibook. Yeah yeah, yeah, it's uh, it's it hasn't been
updated in a little while, but I'm glad that you found that and mentioned
that. Yeah. Yeah, maybe it's just the starting point. Yeah,
maybe you can just get Yeah cool, Okay, thank you, Peter,
Chris, what's up all right? Yeah, first I want to say thanks
a lot, Deane. That was that was really awesome. Uh, I
could just I just had flashbacks of all the pain points you mentioned with with
race conditions and and unfortunately I am the last person I always try and do
it with just react and maybe that's probably a dumb decision. So I'm I'm
sold on. I'm going to try out your library, and I'm I'm working
on stuff where I really need a lot of this this concurrency and and all
this queuing stuff. So but yeah, really thanks a lot, and I've
I've looked a little bit on the repo and and yeah, it looks awesome,
so I'm I'm happy to try it. So with that, I'm just
gonna link to my blog. I as I mentioned, I have a few
projects coming up with with automation and hopefully some some RxFx in there and a
few things with AI. So yeah, thanks, cool, cool, all
right, and Charles, how about you? I left this last one for
last. I don't know about best, but anyway, so I've got a
couple of things going on here lately. I'm gonna be really brief with the
technical stuff because there's something else that I kind of want to say. So
first of all, I'm right in the thick of actually putting together summits for
Ruby, React and JavaScript. The Ruby summit will be in February, the
reacts and it will be at the beginning of March or the middle of March,
and the the JavaScript Summit will be in April, and you know you
can you anyway. I'll have information up I own. I already owned the
domains because I've done summits before. I'm doing these a little different. If
you go sign up with your email, you'll get emails when the talks are
released. I'm not doing any live element to it this time. And basically
what I'm doing is I'm asking the question, what's the future of whatever,
right of Ruby, React or JavaScript? Right, and so people can talk
about what they see coming or if they have expertise in like machine learning or
something else, right, then maybe they'll just inform that part. But anyway,
yeah, so the second week of each month is when I'm planning on
doing those, so keep an eye out for those. I'm also pulling together
some challenges to just level people up on stuff. So yeah, I watch
for that as well. But the thing that I really want to talk about,
and I'm you know, to get a little heavy, folks. It's
going to be a little bit of a downer. And if I know certain
people get I hate the word triggered, but I know certain people are sensitive
to people talking about self harm or suicide, and so if if it's going
to bother you, then this is the time that you skip to the next
episode that you're going to listen to. So right before Christmas, the Tuesday
before Christmas, my brother tried to kill himself and he failed. He bought
himself a pistol and tried to shoot himself and his hand moved and so instead
of shooting himself in the brain, he shot itself through the eyes. And
so he's blind now. But anyway, so for the last like four weeks,
you know, I've been at the hospital and I've been trying to help
my mom figure stuff out all kinds of different things, and things got pretty
dark for me, to the point where I actually went and talked with therapist.
By the time I got to the therapist, I was actually mostly past
all the anger and everything else that you kind of feel in these situations.
But I want to encourage people that if you are feeling if you're feeling in
that dark place, to go get help right and don't go through it alone.
And then the other thing is is that if you have a family member
or a friend or somebody who you know is feeling that kind of He said
he felt stuck in his life and you know, wasn't it wasn't going to
change. And I imagine a lot of people are feeling that right in different
ways. And so that's the other piece is if you're if you're feeling so,
if you're feeling low, go get help. And if you have a
family member that's a little bit of a loaner or you know, exhibit certain
level of frustration with their life or things like that, just be therefore,
you know, just just talk to them, see if you can get them
to open up see if there's something you can do to help them. And
then the other piece to this is, as I've talked to friends in various
circles that I that I operate in here in my personal life, you know,
at church, or I'm fairly involved politically, and you know, I
had some people relying on me for things that I had to push back,
and so I explained what was going on. I found that a lot of
people encounter this. I had a lot of people tell me, hey,
look, I had a brother, or a child, or a spouse or
a friend that tried to kill themselves or in some cases they succeeded. And
so that's the That's the last thing that I want to just point out is
if you're going through something like this where you know you're struggling because a family
member or a friend attempted to a side, or you know is just going
through something really hard, don't keep it to yourself because you're not the only
person going through it. You know. One of the things that really helped
me is my two best friends and I we get together every week, well
three of my best friends now because we invite another guy into the group.
We play board games and so we got together and we played board games and
just talked. Right, I just talked through my thing. And you know,
one of my other friends, he's struggling with his marriage and he's talked
through his stuff, right. My the other guy in our group lost a
child last year and so you know when that, when he went through that,
we talked through it. And you know, so go find people that
you can open up to. And I don't know, I don't know if
there's anything concrete that I'm looking at, you know, necessarily put out there
other than that. We all go through stuff, right, We're all broken
in some way, and you don't have to do it by yourself. So
I if there's any message I can just put forward today, it's that,
okay, So, and thank you for I couldn't have put this out a
week ago because I was still an emotional mess. But you know that's the
other thing is I've been able to work through a lot of it. So
thank you for talking about it and destigmatizing it. And I know it must
have been hard for you to get to this point. Yeah. Well,
you know, like I said, people have helped me out with it,
and you know, holding it in you feel like you're all by yourself and
you're just you're not so anyway. Yeah, dude, that is some heavy
stuff that I think definitely needs to be addressed more and in situations where it's
just not necessarily expected. Like for those of you tuning into the show,
you probably didn't join today's episode expecting to receive content about that. But the
thing is, it's not supposed to warrant an entire like scenario to talk about
this. This should be something that we talk about when there is something to
be said, not when like we create an entire environment just to talk about
this particular thing in this like mentioning this in here is I believe a good
way forward for society and trying to like address this in each situation where it
is pertinent, you know. So I think this is one of the issues
is like people could we talk about this with their psychologists? Okay, but
what about in the regular day to day life? You know, do you
see other people opening up about what they're actually going through and normalizing that stuff
so that others don't feel like they are comp different? You know, because
a lot of people are going through through different stuff, and a lot of
times the people that are going through it. They just feel that they are
the only ones going through something like that, you know, so there's not
a normatization of this happening with others. And does you feel like the problem
is you? And yeah, so, so I really appreciate that you brought
this up, and it is something that I think. I think you're setting
a good example for bringing it up. I know there is a a completely
sensible subject. Uh, it's got to be be tough talk about those things,
you know, and just knowing that afterwards you could have people reaching out
to you and like you kind of remember something that maybe you didn't want to
remember some time for now. But but I really appreciate that too. Yeahmen,
thanks so guys, thank you so much. Dean again just ending up
with a positive note. Dude, this was awesome. I would Yeah,
it's terrific. Feel free to come back more more times. So I'm sure
that we could like even talk more about just our ex effects, but sure
to a lot of other stuff that we can talk about too. So yeah,
man, please reach out in a couple of weeks or something so that
we can schedule all the episodes. Sure, sure, Thanks, I love
to thank you. Thank you for the engagement of and I felt good.
No words, no words, yeah, okay, thanks everyone, thanks for
sticking with us up until the end, and I'll see you