Solidjs and React.js - Difference and Comparison
Tags: react, solidjs, reactive, javascript
Published: 2022-05-30 13:19:32

[**Solidjs**](https://github.com/solidjs/solid): Solid is a declarative JavaScript library for creating user interfaces. Instead of using a Virtual DOM, it compiles its templates to real DOM nodes and updates them with fine-grained reactions.

[**React**](https://github.com/facebook/react/): React is a JavaScript library for building user interfaces. It uses Virtual DOM to efficiently update and render just the right components when your data changes.

#### Key features of Solidjs:

- Fine-grained updates to the real DOM
- Render-once mental model: your components are regular JavaScript functions that run once to set up your view
- Automatic dependency tracking: accessing your reactive state subscribes to it
- Provides modern framework features like JSX, fragments, Context, Portals, Suspense, streaming SSR, progressive hydration, Error Boundaries, and concurrent rendering.

#### Key features of React:

- Virtual DOM: React uses a virtual DOM to efficiently update and render.
- Provides modern framework features like JSX, fragments, Context, Portals, Suspense, streaming SSR, progressive hydration, Error Boundaries, and concurrent rendering.
- Maintained by Facebook and the community.

### Side by side comparison Solidjs vs React(functional component)

#### Components:

##### React:

React components can be created using class-based syntax or function-based syntax. Components are functions that return JSX.

```jsx
// Function-based syntax
const Hello = () => <div>Hello</div>;
```

##### Solidjs:

Components are functions that return JSX.

```jsx
const Hello = () => <div>Hello</div>;
```

**Note:** Solidjs and React both use the same JSX for templates.

---

#### State: State is a plain JavaScript object that is used to record and react to user interactions.

##### React:

A state is a plain object. You can create a state using the useState hook. useState takes the default state as a parameter and returns an array of state and state setter functions.

```jsx
const Counter = () => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  // OR
  const increment = () => setCount((c) => c + 1);
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>Click</button>
    </div>
  );
};
```

##### Solidjs:

You can create state(signal) using createSignal hook. createSignal takes default state(signal) as an parameter and returns array of state(signal) and state(signal) setter function.

```jsx
const Counter = () => {
  const [count, setCount] = createSignal(0);
  const increment = () => setCount(count() + 1);
  // OR
  const increment = () => setCount((c) => c + 1);
  return (
    <div>
      <h1>{count()}</h1>
      <button onClick={increment}>Click</button>
    </div>
  );
};
```

**NOTE:** React Hooks can only be called inside the root of the component. Solid createSignal can be used outside of a component.

```jsx
const [count, setCount] = useState(0); // Not allowed
useEffect(() => {}, []); // Not allowed
const Counter = () => {};

const [count, setCount] = createSignal(0); // Allowed
createEffect(() => {}); // Allowed
const Counter = () => {};
```

---

#### Effects(side effect): It's a function that runs when state changes.

##### React:

In React we have to pass the dependencies array to the useEffect hook.

There are 3 ways to do it:

1. Without dependencies array (the effect will be called on every render)
2. With dependencies array (the effect will be called only when dependencies change)
3. With empty dependencies array (the effect will be called only once)

```jsx
const Counter = () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log('I am called on every render');
  });

  useEffect(() => {
    console.log('I am called only when count changes');
  }, [count]);

  useEffect(() => {
    console.log('I am called only once');
  }, []);
  return ...
};
```

##### Solidjs:

In Solidjs we don't have to pass dependencies array like the useEffect hook. It'll automatically detect dependencies and call effect only when dependencies change.

```jsx
const Counter = () => {
  const [count, setCount] = createSignal(0);
  createEffect(() => {
    console.log('I am called only once');
  });

  createEffect(() => {
    console.log('I am called only when count changes',count());
  });
  return ...
};
```

---

#### Lifecycle: It helps to monitor and manipulate the state.

##### React:

```jsx
const Counter = () => {
  useEffect(() => {
    console.log('I am called onMount');

    return () => console.log('I am called onUnmount');
  }, []);
  return ...
};
```

##### Solidjs:

```jsx
const Counter = () => {
  onMount(() => console.log('I am called onMount'));
  onCleanup(() =>  console.log('I am called onUnmount'));
  return ...
};
```

---

#### Refs: It's a way to access DOM elements.

##### React:

```jsx
const Counter = () => {
  const ref = useRef();
  useEffect(() => ref.current.focus(), [ref]);
  return <input ref={ref} />;
};
```

##### Solidjs:

```jsx
const Counter = () => {
  let ref;
  onMount(() => ref?.focus());
  return <input ref={ref} />;
};
```

---

#### Props: It's a way to pass data to components. It's a plain JavaScript object.

##### React:

Props are passed as an object and can be destructured.

```jsx
const Counter = (props) => {
  return <div>{props.count}</div>; // Valid
};

const Counter = ({ count }) => {
  return <div>{count}</div>; // Valid
};
```

##### Solidjs:

Props are passed as an object and can't be destructured.

```jsx
const Counter = (props) => {
  return <div>{props.count()}</div>; // Valid
};

const Counter = ({ count }) => {
  return <div>{count()}</div>; // Not Valid
};
```

---

#### List of Components/Elements:

##### React:

For multiple lists of data to be rendered, we can use the `map` function.

```jsx
const Counter = () => {
  const list = [1, 2, 3];
  return (
    <div>
      {list.map((item) => (
        <div>{item}</div>
      ))}
    </div>
  );
};
```

##### Solidjs:

For multiple lists of data to be rendered, we can use the `map` function or For component.

```jsx
const Counter = () => {
  const list = [1, 2, 3];
  return (
    <>
      {list.map((item) => (
        <div>{item}</div>
      ))}

      <For each={list} fallback={<div>Loading...</div>}>
        {(item) => <div>{item}</div>}
      </For>
    </>
  );
};
```

---

#### Conditional Rendering: It's a way to render a component based on condition.

##### React:

```jsx
const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <h1>{count < 5 ? "True Value" : "Falsy Value"}</h1>
      <button onClick={() => setCount(count + 1)}>Click</button>
    </div>
  );
};
```

##### Solidjs:

```jsx
const Counter = () => {
  const count = 5;
  return (
    <div>
      <h1>{count < 5 ? "True Value" : "Falsy Value"}</h1>
      // OR
      <Show when={count < 5} fallback={<h1>Falsy Value</h1>}>
        <h1>True Value</h1>
      </Show>
    </div>
  );
};
```

**Note:** Solidjs doesn't rerender the component. It'll always render the first evaluated value.

```jsx
const Counter = () => {
  const [count, setCount] = createSignal(0);
  const TrueCase = (
    <div>
      <h1>From True Value </h1>
      <button onClick={() => setCount((c) => c + 1)}>Click {count()}</button>
    </div>
  );

  const FalseCase = (
    <div>
      <h1>From False Value</h1>
      <button onClick={() => setCount((c) => c + 1)}>Click {count()}</button>
    </div>
  );

  if (count() < 5) return TrueCase;
  return FalseCase; // Never render this
};

// Solution:
const Counter = () => {
  const [count, setCount] = createSignal(0);
  const TrueCase = (
    <div>
      <h1>From True Value </h1>
      <button onClick={() => setCount((c) => c + 1)}>Click {count()}</button>
    </div>
  );

  const FalseCase = (
    <div>
      <h1>From False Value</h1>
      <button onClick={() => setCount((c) => c + 1)}>Click {count()}</button>
    </div>
  );

  return (
    <Show when={count() < 5} fallback={FalseCase}>
      {TrueCase}
    </Show>
  );
};
```

---

#### Context: It's a way to share data between sibling/child components.

##### React:

```jsx
const CountContext = React.createContext(0);
const Provider = ({ children }) => {
  const [count, setCount] = useState(0);
  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
};

const Counter = () => {
  const { count, setCount } = useContext(CountContext);
  return <h1 onClick={() => setCount((c) => c + 1)}>{count}</h1>;
};

const App = () => {
  return (
    <Provider>
      <Counter />
      <Counter />
    </Provider>
  );
};
```

**Note:** use can use context with useReducer, Instead of directly calling setCount.

##### Solidjs:

```jsx
export const CounterContext = createContext([{ count: 0 }, {}]);
export function CounterProvider(props) {
  const [state, setState] = createStore({ count: props.count || 0 });
  const store = [
    state,
    {
      increment: () => setState("count", (c) => c + 1),
    },
  ];

  return (
    <CounterContext.Provider value={store}>
      {props.children}
    </CounterContext.Provider>
  );
}

const Counter = () => {
  const [state, { increment }] = useContext(CounterContext);
  return <h1 onClick={increment}>{state.count}</h1>;
};

const App = () => (
  <CounterProvider>
    <Counter />
    <Counter />
  </CounterProvider>
);
```

Solid offers many more features like a store for state management check the API [doc](https://www.solidjs.com/docs/latest/api) for more info.

#### Live Demo: [Counter Demo](https://playground.solidjs.com/?version=1.4.1#NobwRAdghgtgpmAXGGUCWEwBowBcCeADgsrgM4Ae2YZA9gK4BOAxiWGjIbY7gAQi9GcCABM4jXgF9eAM0a0YvADo1aAGzQiAtACsyAegDucAEYqA3EogcuPfr2ZCouOAGFaEFxVxZe9Mm4eXj68AGLcUrLyiip0Gtp6FlY23HwCjnDOcADKuNxwkXIKyqrxugZkeUJJEFZwFLZ8zB6VvO70nuLund68ALwOTi7dwQAUoLxoLjBkiLzAALpSviCSCwCUlhD1jbIdzLhoHm0MnYwACvIAbprio4TyhLNQEPjr-Fa8Di18wJVZvgCuFyWSWAwyWVy+VGAimcBmcwetCeADo4TNeAAfTHzBaSTafb4QVqVfKIF74frzQlff4uLA0j4QL4s3hQEQiOajK5QNSICD0GAmcTvPoAPl4QJBLlGKnRZBUvlG8tFEuAKI18t8PLUGwZzNZDjUmUYXNVkrgwNwWVl7GmCuwvFG5sW631hsE8NoVzgXPR-MFwsY5ql1plcvtiqdKv6EvlKJkaDULkYo2VAaFIvFk14AEI+gN0es3YzJO7eAstoShLgmMzZQavgAedpnEb1XAoy7e24SHX0OB9ECkoSSMWMr4gJGo5gACyTIiEEEkjKb+lbKfb3i711744NBOXViszWJfA34ipztjTK+p9afzDcBWbI5WGYxqgjF8Qhg3oKaxUv4gQ9LgTYUmKowXowW64IeXw1nWvBNiIaBXJKBDGkOIATiUqCMAA5hgKhzAA5AAjL+pGlmOq4mPQuB5AaHiuBozAANZDte2bsiIox0nAaL2iixoQARuCzrwADUvDkes0iVPgWEgDhjYsio+FERAWiMGgBGzrgJG8BRVE0RKACCHLIfo9GMR4+6sk2tlMV8LFsZxIAfiaY6sSa1nOfZq7hBImRzkOAlCfCZC0Wpk7pgKmbBjeoxNrO5G8G5aAcVx5q-v+yryWKIBoJIa5pWK8mrvowUOSya6oVc+6SFWED3nw5mEIQV7mg2zbQd2NxiIwtV9acKa8PotVrv1u5Dfuh5LkNabmk2HVdZNvgiLQzCCsInYEZaACixrwJ4ABC+AAJJ8SoUCdSo6y5oeYBrEAA)

---

Thank you for reading 😊

Got any questions or additional? please leave a comment.

---

##### Must Read If you haven't

###### [useAsync hook with cache](https://dev.to/devsmitra/useasync-hook-with-cache-5817)

###### [Getting started with SolidJs – A Beginner's Guide](https://dev.to/devsmitra/getting-started-with-solidjs-a-beginners-guide-5af4)

###### [React best practices and patterns to reduce code](https://dev.to/devsmitra/no-more-redux-action-creators-functions-30j)

###### [3 steps to create custom state management library with React and Context API](https://dev.to/devsmitra/3-steps-to-create-custom-state-management-library-with-react-hooks-and-context-api-1bfh)

###### [How to cancel Javascript API request with AbortController](https://dev.to/devsmitra/how-to-cancel-javascript-api-request-with-abortcontroller-36cm)

###### [13 Typescript Utility: A Cheat Sheet for Developer](https://dev.to/devsmitra/13-typescript-utility-a-cheat-sheet-for-developer-ab3)

---

###### More content at [Dev.to](https://dev.to/devsmitra "Rahul Sharma(DevsMitra)").

###### Catch me on [YouTube](https://www.youtube.com/channel/UCQkvNcHN5vg3jEoeOb9Tdrw?sub_confirmation=1 "Rahul Sharma(DevsMitra)"), [Github](https://github.com/devsmitra "Rahul Sharma(DevsMitra)"), [Twitter](https://twitter.com/devsmitraa "Rahul Sharma(DevsMitra)"), [LinkedIn](https://www.linkedin.com/in/rahul-sharma-18b8b374 "Rahul Sharma(DevsMitra)"), [Medium](https://devsmitra.medium.com "Rahul Sharma(DevsMitra)"), [Stackblitz](https://stackblitz.com/@devsmitra "Rahul Sharma(DevsMitra)"), [Hashnode](https://devsmitra.hashnode.dev "Rahul Sharma(DevsMitra)"), [HackerNoon] (https://hackernoon.com/u/devsmitra "Rahul Sharma(DevsMitra)"), and [Blogspot](https://devsmitra.blogspot.com "Rahul Sharma(DevsMitra)").