Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for SolidJs the new React, but better 😎
Tauan Camargo
Tauan Camargo

Posted on

     

SolidJs the new React, but better 😎

Introduction

I started working professionally with react about 4 years ago, I had the pleasure of seeing this library become what it has become today, before we had to createsmart components extending theComponent class of react, then we had the introduction of hooks where when instead of using class components we used function components with the[useState, useEffect, useMemo, useContext, useReducer] hooks, this made the verbosity of the code slightly decreased.

"OK, but isn't this post about SolidJs?"

To talk aboutsolid-js we have to give a context of how things are done inreact.

Here's an example using react Hooks for a simple counter component.

functionCounter(){const[count,setCount]=useState(0)useEffect(()=>{setInterval(()=>{setCount(count+1)},1000)})return<div>Count:{count}</div>}
Enter fullscreen modeExit fullscreen mode

"But wait, this useEffect keeps popping me a warning", yes, it will say that a dependency is missing in theArray dependency of useEffect, let's add it to stop the warning.

functionCounter(){const[count,setCount]=useState(0)useEffect(()=>{setInterval(()=>{setCount(count+1)},1000)},[count])return<div>Count:{count}</div>}
Enter fullscreen modeExit fullscreen mode

Let's run the project:

Re-run glitch

But now we face another problem, after a few years working with react we started to fight this problem daily, the famousre-run, we can solve thisre-run problem in the Counter component in a few ways:

  • Returning fromuseEffect a function that clears thesetInterval
  • UsingsetTimeout instead ofsetInterval (a great practice but the above approach would be necessary to clean the function)
  • Using the function itself to return the previous value directly as the current value

Let's use the last option here:

functionCounter(){const[count,setCount]=useState(0)useEffect(()=>{setInterval(()=>{setCount(prevCount=>prevCount+1)},1000)},[])return<div>Count:{count}</div>}
Enter fullscreen modeExit fullscreen mode

We came up with an idea that react has a "false reactivity" 🧐 .

Let's talk a little about SolidJS

First of all, solid-js is not trying to re-invent the wheel, solid-js is identical to react, let's create our Counter component using solid-js.

functionCounter(){const[count,setCount]=createSignal(0)setInterval(()=>{setCount(count()+1)},1000)console.log('the counter called!')return<div>Count:{count()}</div>}
Enter fullscreen modeExit fullscreen mode

We see a big difference here,count in solid is a function. in solid this is calledaccessor and this is one of the mystical things behind how solid works. Okay, we noticed in react that we have to clean the setInterval or get the value of thesetCount function itself to return the previous value as the current value, to be able to work without the famousre-render, right?

No, :D only this code already works.

We added aconsole.log to check how many times this component was rendered during the count update, we will check how many times it runs in the console:

Image description

Magic!!!! In solid your code does not run more than once unless it is required at some point in the code.

But how does Solid work?

Solid's data management is built around a set of flexible reactive primitives that are responsible for all updates. It has a very similar approach to MobX or Vue, except it never trades its granularity for a VDOM. Dependencies are automatically tracked when you access their reactive values ​​in your effects and JSX View code, Solid primitives come in the form of create calls that usually return tuples, where usually the first element is a readable primitive and the second is a setter. It is common to refer only to the human-readable part by the primitive name.

Primitives

Solid is composed of 3 primary primitives:Signal,Memo andEffect. At its core is the Observer pattern, where Signals (and Memos) are tracked involving Memos and Effects.

Signals are the simplest primitives. They containget andset value and functions so that we can intercept when they are read and written.

const[count,setCount]=createSignal(0);
Enter fullscreen modeExit fullscreen mode

Effects are functions that involve readings from our Signal and are executed again whenever the value of a dependent Signal changes. This is useful for creating side effects such as rendering.

createEffect(()=>console.log("The latest count is",count()));
Enter fullscreen modeExit fullscreen mode

Finally,Memos are cached derived values. They share the properties of Signals and Effects. They track their own dependent Signals, rerunning only when they change, and are themselves traceable Signals.

constfullName=createMemo(()=>`${firstName()}${lastName()}`);
Enter fullscreen modeExit fullscreen mode

How does this Signal work?

Signals are event emitters that contain a list of signatures. They notify their subscribers whenever their value changes.

Things get more interesting as these subscriptions happen. Solid uses automatic dependency tracking. Updates happen automatically as data changes.

The trick is a global stack at runtime. Before an Effect or Memo executes (or re-executes) its developer-provided function, it pushes itself onto that stack. Then any Signal that is read checks if there is a current listener on the stack, and if so, adds the listener to its subscriptions.

You can think like this:

functioncreateSignal(value){constsubscribers=newSet();constread=()=>{constlistener=getCurrentListener();if(listener)subscribers.add(listener);returnvalue;};constwrite=(nextValue)=>{value=nextValue;for(constsubofsubscribers)sub.run();};return[read,write];}
Enter fullscreen modeExit fullscreen mode

Link Github SolidJs:SolidJS

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Senior FullStack Engineer 💻 web | 📱 mobile | 🖥️desktop | 8+ Years Experience | Let's connect! 🌟
  • Location
    Anápolis - Go
  • Work
    Full Stack Developer
  • Joined

More fromTauan Camargo

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp