Transcript
This transcript was autogenerated. To make changes, submit a PR.
Jamaica real
time feedback into the behavior of your distributed systems and observing
changes exceptions errors in real time allows
you to not only experiment with confidence, but respond instantly
to get things working again.
Close hey
everybody, it's Travis Waithmair, and today I'm going to be giving you an intro
to SolidJs for react developers or anyone else.
Now quickly, a little bit about me. I'm Travis Waithmair.
I'm at Twitter travis waithmair in camel case
and I have a blog at nontraditional dev.
I work for plaques and I also
am the creator of the bedrock Layout primitive library that is
originally written in react, but also has a port over in
solid JS.
Now Solid JS has a very familiar
API to react. In fact, anyone who's written a react app,
just looking at this code with no explanation probably
can figure out what's going on. It's pretty easy. And that's because of
that very familiar API that it has from reactjs.
Because for one thing, SolidJs uses JSX,
it uses components and it uses props. And all
of it is very similar to the way react does. In fact,
if you look at this very simple component, very contrived component,
you wouldn't know if this is a solid component or a
react component because it works either way.
These also has solid
also has an API that's very familiar to hooks.
So it has a bunch of these reactive primitives.
And if we look here, this create signal looks very
much like a use state. Create effect feels very much like use
state. And so that very familiar
API that you have in react translates very well over into solidjs.
Now before we go on, I do want to emphasize that solid is not
a drop in replacement for react. You cannot just
import from solid instead of react like
other frameworks, for example preact. But you
can take a lot of that familiarity and intuition
that you've learned from react and hit the ground running in solid.
What makes SolidJs different than
react is how it's built under the hood. And the
biggest thing is it's built on reactivity instead of the
virtual dom.
See, the reactjs virtual Dom, if you're not already aware,
works something like this. This is a very simplified version, but it
effectively works like this. You have components,
something changes state in any of those components, it gets flagged
by the virtual dom that it needs to change, and then eventually it rerenders
the whole time. All that happens. The browser dom is only impacted
at the actual rendering stage. This is where react tries
to be efficient, because it can do more and
do more quickly in memory with a virtual dom,
and then only change the actual dom when it actually needs
to.
SolidJs, on the other hand, doesn't have
a virtual dom. It instead will surgically update
only those parts of the apps that are dependent on the reactive values.
And when those reactive values change, it will surgically
go in and update that. Well,
how does it do that? What's the magic? Well,
SolidJs is a compiled framework which,
let's be honest, everything is a compiled framework. Nowadays,
even react. You're not actually technically writing JSX,
you're compiling that to react,
create element calls. But it's in that
transpolation that with their fine grained
reactive primitives, that solid js will do all that wiring
up for you. So you just write the code how you
want. That feels very pragmatic, very intuitive,
and solidjs under the hood when it gets transpiled, will do
all that wiring up for you.
See, in solidjs it's all about the primitives.
There are components in solid, but they're not the foundation like
they are in other frameworks. In fact,
with solid the component actually disappears.
Your component only renders once and then it never renders again.
It's the finegrained reactive primitives that solidjs
is built on that make everything happen.
And in fact, everything in solidjs can be broken down into
one of three primitives. It's either a signal, a memo,
or an effect. A signal
is simply but and easy to
think about is a function that returns a value.
So when we use create signal, we get a
signal and a setter for that signal, and then
we get the value just by calling the function. And these,
if we want to set it, we would call the set count function. In this
example, effects,
on the other hand, allow us to do effects based on
those signals and when they update. And so in here
we're updating the document title to whatever the current count
is, and now you'll notice coming from react,
you're going where is that dependency array? Well, there's none needed,
because that create effect already knows to rerun only
if the count signal is updated.
And then memos are kind of an amalgam of both
an effect and a signal. See,
it will only rerun if any of those signals
that it depends on actually update.
And then it returns a signal itself that you have to call
to get the value. So obviously these
memos by its name work best for expensive calculation.
And you'll notice, just like the create effect,
no dependency array.
So let's just go through these simple counter function. We have a
create signal at the beginning we have count, set count.
We have an effect that will update the
document title whenever the count is updated. And then we have some JSX.
One is a paragraph that will tell us what the current
count is, and a button that when we click it
will increment. The counter once again
feels very familiar to the way we built things with react.
The cool thing though is that every time we hit that set
count, we don't rerun this entire counter function.
The only thing that gets updated is that effect reruns, and then
that paragraph JSX reupdates
and that's it. Nothing else is even
touched.
Primitives don't follow the rules of
react because components are
only ever run once and never run again. There's nothing to
say that we can't conditionally call an effect.
We can't conditionally call a primitive
in a hook to do any of these stuff that I'm doing here. In this
example, if we were doing this in react, these would break your app,
but with solid these is
totally fine. And in fact, you notice that the signal
we pulled out of the component and
brought it into a more global area of
the module. This is a very common way to create a
global state. You just pull the signal out of the component
and now it's available to be imported into
any component, and those components will both be
kept in sync because they're dependent on the same signal.
Now it's important to note that
even though this is a common way to update state to have global state,
there are more complicated ones that handle more sophisticated
use cases. And all of that's available in the API,
in the docs at solidjs.
Now there are gotchas if
you're coming from react if you're a react developers. And I
like to use this example when explaining that as an english
speaker, Spanish has a lot of false friends.
For example, the word university in Spanish is universidad.
In English we have the word president, and in Spanish it's presidente.
And in English we have the word embarrassed.
So we might think the word for embarrassed in
Spanish is embeddesada. But any of my spanish speaking friends
who are listening to this would know embedasada means pregnant,
not embarrassed. So sometimes familiarity
will create us a false sense of confidence
and will break things if we're not aware. So just in
the same way, solid has its false friends for react developers.
So let's look at one of the most common ones.
Don't return early in solidjs components.
Remember, Solidjs has only runs these components once,
and if you return early,
the rest of that component is
never run. And hence the reactivity and all that
stuff that happens under hood never happens. And therefore,
even though that prompts that data gets updated,
we never actually get that reactivity and go on
to the rest of the component, because the component never reruns.
So what you want to use instead are control flow components.
SolidJs has several control flow components to help us
do the things that we normally would have done otherwise in react without
breaking reactivity. In this example we're using show that when props
data exists, it will show
its children and then it has a fallback in case it doesn't.
And there are control flow components like switch for air boundaries and
suspense. Now another thing
you don't want to do inside a solidjs component is do logic
outside of the reactive primitives or outside
of JSX. You can always do
do logic inside of an effect,
a memo or any other primitives or JSX and
it works great. But as soon as you do it outside of
that such, in this example, we're deriving a double count value from
our count signal. That value gets lost
in the scheme of things, that wiring up of reactivity
never happens. So what we want to do, we can
drive the value, for example in a function, if we put it in a function,
these the function,
since it's ultimately called in the JSX, in this example, that reactivity
still gets wired up just fine.
Or better yet, if you can, if it makes sense,
just put it right into the JSX.
And that also works.
Now this is a big one that happens pretty much to every new
react developer when they come into solidjs.
And that's because it is common in react to destructure,
your props either directly in the component signature
or immediately react right after.
And both of these are no no's and you might go,
why does that break reactivity?
Well, if you think about it, prop values could be
reactive. And I'm going to give you a little peek under the hood of what
happens when your prompts do
have a reactive value under the hood. Solidjs will see
that. And instead of doing a regular property
value like the salutation that says hello, it will actually do
a getter that will return the value that is called.
So whenever that prop value name gets
called, it's actually calling the signal username under the hood.
So essentially every prop value needs
to be treated as if it was a signal.
So instead of destructuring them
either in these signature or directly from the prop value,
the props just go ahead and put your props directly
in the JSX. Now sometimes we do need
to manipulate the props and we need to split values or merge values.
And in that case there are utility functions called split props and merge
props that allow you to safely split or
merge those props without breaking that reactivity.
And one that I think is very great
because there is no don't do in this case,
but in solidjs because your components only ever
run once. You don't need to have useref or use
callback. You can just assign your refs to
a value or you can pass
functions directly into your
components and you don't have to worry about having callback. Doing use callback
because you don't have to worry about your component rerunning and having
to make sure you get the same exact ref or the same exact callback
function. So don't go looking around
for used ref or used callback or an equivalent because they don't exist,
because they're not needed.
Now after giving you all those gotchas, you might be like, well,
it's not worth it. That's too much to remember.
Just like react has linter
for reactJs hookdools, Solidjs has its own linter
to help you make sure you don't break reactivity.
Now one might go, well, why bother? ReactJs is at
the top, there's the highest market share. SolidJs is these
just new up and coming thing. Why even bother
learning it? Well, SolidJs has
the highest satisfaction rating according to the state
of JS in the 2021 results. And this is because
it was the very first year that it was actually on the list.
It beat. But every other framework in
its first year,
it's also very performant by default. Ryan Carniato,
the creator of SolidJs,
loves being performant, but not at the expense
of developers experience. And because of that he's built this fantastic
API that you don't have to worry about performance,
it does it for you.
There's already a robust ecosystem.
If you go to solidjs.com slash ecosystem, you can see
there's already multiple routers, UI components, tooling starters.
A lot of the things that already exist in other frameworks already exist
in solid JS as well. So you can build a full
on app without having to worry about whether there's
a plugin or an ecosystem that is going to
support your app. By the way, here's a shameless plugin for
solid bedrock layout, which is my port of my
react library. Over to Solidjs and
there's also in the works, it's in beta right
now, but there's a meta framework just like remix
or next. And it is built
on solid. It's called solid start and you can go check that out at these
link. So where do I go from here?
You're like, I'm sold. I want to learn all about Solidjs.
Well, great place is solidjs.com. That's the doc
site. Specifically, I would like to
recommend that you go to the tutorial. It'll go through all the basics and
you can really get into it as well as there's a playground where
you can learn and just play around with Solidjs and mess with
the reactivity and see how it works.
And then of course there is a discord for Solidjs.
Highly recommend. It's a fantastic community of developers who
support each other and that's it.
Thank you. I'd like to thank you for the time here and hope you enjoy
the other talks at the conference. Once again, my name is Travis Waithmair
at traviswithmare on Twitter and I blog at nontraditional dev.
Hope you have a great one.