How to use RxJS with React Hooks
Summary
TLDREn este video tutorial, exploramos el uso de RxJS en combinación con React Hooks, asumiendo un conocimiento previo de React. Comenzamos con una introducción a RxJS y los Observables, destacando su capacidad para manejar múltiples valores a lo largo del tiempo, a diferencia de las promesas. Después, nos sumergimos en ejemplos prácticos usando CodeSandbox, donde implementamos Observables básicos y los integramos en componentes de React, primero con clases y luego con Hooks para una sintaxis más limpia y menos verbosa. Finalmente, aplicamos estos conceptos en un ejemplo real de búsqueda de sugerencias usando la API de Pokémon, demostrando la potencia y eficiencia de RxJS para el manejo de eventos y datos asincrónicos en aplicaciones React.
Takeaways
- 😀 RxJS es una biblioteca de extensiones reactivas para JavaScript que permite la programación reactiva utilizando observables.
- 🤔 Los observables son colecciones invocables de futuros valores o eventos que pueden enviar múltiples valores a lo largo del tiempo, a diferencia de las promesas que solo se resuelven una vez.
- 🚀 RxJS permite la ejecución perezosa, lo que significa que las operaciones complejas no se ejecutan hasta que se suscriben a ellos.
- ✨ Los operadores de RxJS permiten transformar y componer observables, lo que brinda una forma poderosa de procesar datos asincrónicos.
- 🎣 Puedes utilizar RxJS con React Hooks para manejar flujos de datos asincrónicos y reactivos de una manera más limpia y declarativa.
- 🧩 Los Hooks personalizados, como useObservable, pueden encapsular la lógica de suscripción y cancelación, lo que facilita el uso de observables en componentes de React.
- 🔍 RxJS es especialmente útil para implementar casos de uso como búsquedas con sugerencias automáticas, donde se necesita manejar flujos de datos asincrónicos y aplicar operadores como debounce y distinctUntilChanged.
- 🧪 Los Subjects de RxJS actúan como observables ejecutables, lo que permite compartir datos y eventos entre múltiples observables.
- 🌍 Existen bibliotecas de terceros, como rxjs-hooks, que simplifican aún más el uso de RxJS con React Hooks.
- 📚 RxJS es una biblioteca madura y ampliamente utilizada, con una gran comunidad y recursos disponibles para aprender y profundizar en su uso.
Transcripts
however now the going team here and
today I want to talk about how to use
rxjs together with react hooks this
video assumes that you are familiar with
react and feel at home with react hooks
so let's start by talking about what is
rxjs and observables rxjs is a reactive
extensions library for JavaScript as it
says on the website and it's essentially
a library for reactive programming using
observables if you are not familiar with
all of those concepts don't worry we're
gonna go over them in a minute now let's
start by talking about what is
observables observables is basically an
idea of an in vocable collection of
future values of events I like to think
about it this way so you have a promise
and promise can only resolve one time
right so it can either be a rejection or
fulfillment but it will only resolve
once while observable have an option of
actually sending more than one value or
event over time and this is essentially
what you have to know about observables
right the cool thing is that observables
are actually in process of getting
standardized into ACMA scripts there's
been some problems with the proposal and
it's still stuck on a stage one but it's
coming to the language sooner or later
at least that's my opinion and there's
like a lot of effort put in the proposal
so if you're curious the links to all
the websites that I'm showing are going
to be in a video description if in case
you want to check them out for yourself
alright now that we got the basics out
of the way let's just jump right into
code sandbox and see how exactly do you
use rxjs and observables in a standalone
fashion right so I'm just going to
create a new vanilla sandbox I'm gonna
add our XJS here as a dependency and
that's basically all we need so what
we're gonna do is we're gonna implement
a very basic observable that will show
us the numbers right so I'm not I'm not
even gonna render it in this case I'm
just gonna import from from rxjs
so this is the from operator allows you
to create observables from other
iterable things or in some other special
cases like promises in this case we're
going to create a new
numbers observable right and we're gonna
say from array and in this case is just
gonna be numbers so very straightforward
nothing super fancy here right now let's
say we want to actually do something to
those numbers right so let's say we want
to have squared numbers so how would you
go about that squared numbers is going
to be equal now we're going to take our
observable and pipe its to operator so
called operators which is basically
modification functions which is
something we can import from rxjs slash
operators right in this case let's say
we also we are saying we want to squared
numbers which means that we want to
square them which means we need the map
function right so we're gonna pipe it to
the map function that takes in a value
and then does something to this value
since we're squaring them we're gonna do
exactly that so it's gonna be squared
numbers right now if I try to
console.log this squared numbers we're
actually not gonna see the numbers
themselves but we're gonna see the
observable this is exactly what I was
talking about before so it's a primitive
right now what do we do actually if we
want to see the real numbers we have to
subscribe to it so this is one of the
things of the observables to consume it
you subscribe to it right so we got the
result and if we console.log the result
in this case we're gonna see that we
print out the values one at a time so
this happens for each value right the
whole pipe happens for each value it's
also lazy this is like one of the
strengths of the observables they are
executed lazily which means that okay
say we have this range say we want to
filter so we're going to auto import the
filter function from the observable
operators and say we want to say okay we
want all the values that are larger than
two what the laziness means is that
actually the square the map that we
define here it's only going to be
executed after the filter is done so
it's not gonna do any work whatever the
complex pipelines you have there after
the filter on any of the values coming
before that this is like one of the
bigger
things about the observables right this
is the basic usage so it's very
straightforward worth noting that
basically once you subscribe you get the
subscription objects and you can
unsubscribe from it so say if we want
the for some reason to dispose of it
right so we're going to console.log the
first number we get and then we're gonna
say subscription dot unsubscribe which
will result in us just getting the first
number and then everything else again is
going to be discarded and never executed
because observables are lazy and if
nobody is subscribed to them they're not
gonna do anything okay so this is the
basic case now let's talk about the
usage of observables in react without
hooks so like the you know the the old
standard way of doing that so we gots
the code sandbox for react here once
again I'm gonna import rxjs and we won't
actually be needing any new files here
so I'm gonna just you know copy this
code we have over here because let's
just start with implementing the exactly
same thing but rendering the numbers
inside of our react app right so how do
you go about that well in this case we
got the function components so let's
make it into a class stands react start
components right and this is gonna be
our render method and we need another
closing bracket there we go okay so now
we got the class rendering as expected
so what do we have to do to work with
observables well first of all we need to
define a column sorry the estate because
it will need to be updated so the our
component has to react to the changes
right I forgot the super over here and
we're gonna say okay that current number
is one for example I guess let's start
with zero because we don't have zero in
our numbers array right and okay so we
define that we set the state so now we
can actually render it let's create a
simple render here current number is
this states that come on state current
number right so we got that now we need
to actually listen to the observable so
we obviously cannot just subscribe to it
and never unsubscribe because they will
lead to memory leaks and problems in the
long term with the amp so that means
that we have to handle two things we
have to handle component did mount right
so this is where we set up our
subscription this is exactly what we
want to do but instead of saying that
let's subscription we're gonna say this
subscription and store it on the
component itself right and in this case
we're not gonna unsubscribe here and
instead of using console.log we're gonna
set States to our current number result
right so this is exactly what we want to
do now this works we get our final
number because the numbers are being set
dynamically but the problem is that on
every mount on every refresh on every
page change for example this is gonna
result in more and more listeners set
right which is not something we want
which means that we need to clean up
after us so on component will unmount
we're gonna say this subscription and
subscribe not too bad right so it's it
works but yeah it's not far from being
perfect essentially right now let's make
it more interesting so let's say we want
to see the numbers dynamically here in G
right so let's how do we do that well
there is a delay function that that is
one of the operators for HGS and let's
say we want to see one number per second
so if we do that you see it actually
kind of works but it still shows us only
the last number this is because the
delay is applied to all of the values
instantly right so we go through all of
them and you set the delay for one
second for each and while the delay is
there it still applies it to every value
which is not something we want to see so
what we actually want to do is again one
of the probably the most powerful
features of our XJS is we want to merge
map the value into a new observable that
will be delayed so there's the merge map
operator merge map right
it takes the function that
the value and returns something new so
in this case we're gonna say that we
create a new observable from an array
that only contains our value so we're
gonna pipe it into one second delay
multiplied by the number so that the
delay is increased every time right and
as you can see here we finally have our
result that is working so we actually
can see on the page reload that the
number increases over time right so okay
we're skipping the value one and two in
this case so the we're getting three
four and five seconds delays but it
works as expected right so pretty
straightforward still that is a lot of
code to set this up and if you would
have to do that in every component that
consumes observables is just not as
convenient right so let's rewrite that
to work with hooks first of all we're
gonna change this into a function again
right so we're going to have a function
f that is this and it returns the
renderer as before so this works
perfectly fine this doesn't have to be a
render anymore so we can just return
this right let me just format this real
quick now instead of this state and
constructor we're gonna have you state
hook so I'm gonna just use the current
number and then we're gonna have set
current number and this is gonna be use
stage which is going to be equal to zero
by default right so there's there we go
there's our state now we have to figure
out how to do the whole subscription on
subscription again if you're familiar
with the react hoax you know that there
is a used effect hook that basically
does exactly what we want
so we're gonna do this and there's our
use effect hook in this case when we
want to run it once I'm gonna provide an
MTA dependencies array because nothing
really changes in this app right okay so
we got the subscription setup well we
have to change something we have to
actually return the dispose function and
we have to set the subscription to the
local variable which makes it a bit
cleaner and okay in this case we should
use the current number over here and
instead of this set state we're gonna
use set current number so the code is
even less verbose than before and as you
can see here it basically works as
expected so in a few seconds we should
see our values
start ticking there we go okay so as you
can see it's a lot nicer when you're
using hooks a lot less verbose you don't
have to do a lot of setup and even
better you can actually easily extract
this use effect hook into a new hook
let's call it use absorbs or use
observable is what we want right and in
this case we're gonna pass in an
observable and we're gonna pass in a
setter function because well observable
has to set something right and I'm just
going to extract this here and say okay
so we're gonna listen to observable and
use a setter function for the result and
in this case since it's a custom hook
it's gonna depends so we're not gonna
run it once but we're actually gonna
change it based on the observable and
setter that are passed to it so in this
case I can just write in my coat okay
use observable we're gonna use square
numbers and we're gonna use set current
number right so once we say that we
should actually see the numbers working
as expected there we go
okay so this is all nice and easy but so
far you know it doesn't exactly seem
useful right so we've been doing all
those things and it's kind of looks nice
a synchronous and everything but how do
you actually apply that in real world
well let's implement a real world
example that is probably in showcased
for well just about every possible rxjs
demo I think Auto suggestion or you know
search suggestion basic right so in this
case I'm gonna use the Pokemon API so I
got the URL over here and which is
basically gonna have a function that
fetches gets up gets get pokemon pokemon
vine eight right so we're gonna have a
function that takes in a name and it's
gonna be a synchronous so it's gonna be
a promise and then what its gonna do
it's gonna fetch okay a weight fetch our
URL so the one that I have this is the
Pokemon API and it basically has 2,000
Pokemon so which is going to grab the
whole array still seeing
unison you know in reality you would
have a proper API that does the search
for you but in this case we're gonna in
this case we're gonna simulate the
synchronicity okay and then we're gonna
get results as Jason and in this case
it's gonna be results and we're gonna
name them all pokemons right so we're
gonna extract this and then what I'm
gonna return is I'm gonna say okay all
pokemons filter Pokemon so that Pokemon
name includes our name right so
basically just filter me everything that
the API returns with the input that user
provided right so simple enough now we
don't really need all of that anymore so
I can just actually kill that but that
will break our app so I will not do that
just yet now here's the thing let's
implement the search first right so
let's I guess we can just kill that
because we're not using we're not gonna
be using it anymore right so we're gonna
have search and we're gonna have set
search right so this is gonna be our
inputs and in this case I'm just gonna
create input type text placeholder
search and then we're gonna have value
search and on change is gonna be handle
search change because we need to do a
bit more than just set the function so
sorry set the value right so get our set
handle a handle search change it's gonna
take an event and we're gonna get the
new value
this is gonna be events targets value
and in this case first let's just set
search new value right so this will
basically allow us to type in stuff in
the search box and now we have it saved
to the state so it correctly updates now
while this works and everything it's not
exactly does it doesn't search for
anything right so how do you actually do
that well we need to create an
observable and then we need to apply
operators to it right so of course we
could create a new observable on every
or change but that doesn't sound
effective luckily for us the rxjs has a
very handy thing called subjects and in
this case we can take a behavior subject
that is gonna be our preset pipeline for
the value processing right so let's
create a new search subject right so I'm
gonna say okay we got our new search
object which is gonna have the default
value that is equal to nothing right so
this is our user I can actually remove
all of that because we don't really need
that we do need to use observable okay
so we created our subject now what we
need to do is say okay search subjects
next right and say new value okay so we
pass our new value to the search subject
which means whoever is subscribed to it
will actually get that value so I'm
gonna create a new state which is gonna
be results and set results and it's
gonna be use stage it's gonna be an
empty array because we're expect an
array of pokemons right and in this case
let me just do a div here and I'm just
gonna json stringify results now to
write so that we can actually see how it
looks so in this case it obviously looks
as an empty array now what we want to do
is we want to use observable right and
we're gonna use our search subject and
then we're gonna use set results to
update it right seems straightforward so
once I start typing it should set the
values which you know it works but
that's not exactly useful right because
we don't really do anything to that
subject now let's create search results
observable which will actually do all
the work for us right so we're gonna
take the search subject and type it into
a new set of operators that will
essentially search for the results for
us right so first of all we want to
filter the input so that value length is
more than one symbol because we don't
want to search for something very short
and Hamor our server with a useless
query is essential right next thing we
want to do is we want to debounce
time and we want to say okay we want to
only execute this after users
typing for 750 milliseconds this can be
tweaked a bit but you know essentially
if user changed his might need way of
typing we want to wait for him to
actually finish it next thing we want to
do is we want to say that okay we only
want to change if the value is actually
changed so if user type something then
changed his mind erased it but then
change the value back again we don't
want to do the same search right and
once this is done we want to merge map
in this case sorry merge map come on I
want to map our value to a new
observable that is going to be created
from our get Pokemon by name promise
right that is going to be searched by
our value so now we need to obviously
use this search result observable here
and this theoretically should give us
the result so if I go into the search
box and search for pull bazaar there we
go so we get our JSON now let's actually
render it correctly because this is not
very user friendly right so we're gonna
take results I'm gonna map them into a
Pokemon which is gonna be a div that has
a key Pokemon name and then I'm just
gonna render Pokemon name over here and
it's gonna be it so very simple
rendering in this case you know this is
not focus of this video so I'm gonna be
very straightforward with it so if we
search we got the names of the pokemons
and if you know if I start typing like
crazy erasing it you can see that it
actually only searches for the last bit
so it never hammers the server it never
does unnecessary work and this is
basically what's really great about our
exchange
white this is basically it's I think we
covered all the basic things here
obviously they're XJS is pretty old
library it's very popular there's a huge
community around it so if you don't want
to write your own hooks or if you're
looking for something very specific
there is plenty of existing libraries
out there for react for example rxjs
hooks that simplify working with rxjs
quite a bit so if you you know if you're
interested if you don't want to write
your own hooks do check it out it might
simplify your life
that is it from my side for today thank
you very much for watching and I see you
next time bye
Ver Más Videos Relacionados
Preguntas para Entrevista Técnica en REACT
useContext en 20 minutos
¿Qué es y cómo funciona useEffect? Hooks de React
Curso Javascript - #04 Objetos literales, Desctructuring y Optional chaining operator
¿Cómo funcionan las Promises y Async/Await en JavaScript? [2022]
🚀 TODO lo que me hubiera gustado que me hubieran EXPLICADO cuando EMPECÉ con REACT
5.0 / 5 (0 votes)