SolidJs the new React, but better 😎
Tags: react, solidjs, javascript
Published: 2022-04-07 05:35:01

---
title: SolidJs the new React, but better 😎
published: true
description: 
tags: #react, #solidjs, #javascript
cover_image: https://repository-images.githubusercontent.com/130884470/ad63fd00-7ab2-11ea-9c57-6c114391183a
---

## 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 create `smart components` extending the `Component` 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 about `solid-js` we have to give a context of how things are done in `react`.

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

```jsx
function Counter() {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    setInterval(() => {
      setCount(count + 1)
    }, 1000)
  })

  return <div>Count: {count}</div>
}
```

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

```jsx
function Counter() {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    setInterval(() => {
      setCount(count + 1)
    }, 1000)
  }, [count])

  return <div>Count: {count}</div>
}
```

Let's run the project:

![Re-run glitch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cgp8oe4rnrkbad0sveho.gif)

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

  - Returning from `useEffect` a function that clears the `setInterval`
  - Using `setTimeout` instead of `setInterval` (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:

```jsx
function Counter() {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1)
    }, 1000)
  }, [])

  return <div>Count: {count}</div>
}
```

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.

```jsx
function Counter() {
  const [count, setCount] = createSignal(0)

  setInterval(() => {
    setCount(count() + 1)
  }, 1000)

  console.log('the counter called!')

  return <div>Count: {count()}</div>
}
```

We see a big difference here, `count` in solid is a function. in solid this is called `accessor` 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 the `setCount` function itself to return the previous value as the current value, to be able to work without the famous `re-render`, right?

No, :D only this code already works.

We added a `console.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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ly3e2n8mn6yqwman9hpz.gif)

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` and `Effect`. At its core is the Observer pattern, where Signals (and Memos) are tracked involving Memos and Effects.

Signals are the simplest primitives. They contain `get` and `set` value and functions so that we can intercept when they are read and written.

```jsx
const [count, setCount] = createSignal(0);
```
`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.

```jsx
createEffect(() => console.log("The latest count is", count()));
```

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.

```jsx
const fullName = createMemo(() => `${firstName()} ${lastName()}`);
```

### 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:

```jsx
function createSignal(value) {
  const subscribers = new Set();

  const read = () => {
    const listener = getCurrentListener();
    if (listener) subscribers.add(listener);
    return value;
  };

  const write = (nextValue) => {
    value = nextValue;
    for (const sub of subscribers) sub.run();
  };

  return [read, write];
}
```

Link Github SolidJs: [SolidJS](https://github.com/solidjs/solid)