七爪源码:React 到 Solid.js:平滑过渡

SolidJS 非常有效地做到了这一点,尤其是对于 React 开发人员

Web 框架来来去去是事实。尽管 Angular 和 React 在 10 年左右的时间里一直主导着市场。但是你在面试中听过多少次以下问题:

你能比较一下 Angular 和 React 吗?两者的优缺点是什么?什么时候使用一个而不是另一个?

但是等等……那么我们实际上只有两个选择吗?一些过于务实的人可能会说这是真的。押注大公司支持并被数百万人使用的框架/库似乎是合理的。它们更可靠,我们更有保证它们将得到长期支持。

但是,您认为什么是高风险的赌注?

我建议看看 Solid.js。一个开源的 JavaScript 库。这个库的提议是带来我们在 React 上找到的好东西并改进其他一些部分,带来一种不同的算法来管理组件渲染(速度非常快)。下面观察 SolidJS 在性能方面与原生 Javascript 的接近程度。这真是太棒了!

但是从 React 切换到 SolidJS 有多难? 一块蛋糕! 在这篇文章中,我将尝试展示如何真正快速地迁移到 SolidJS!


基本结构和语法

Solid 只支持功能组件。 观察下面的例子:

import { Component } from 'solid-js'; const BasicComponent: Component<{value: string;}> = ({ value }) => {  return {value};};export default function Form() {  const handleMouseMove = (event) => {    console.log(event.clientX, event.clientY);  }    return (                );}

还有什么比这更类似于 React 的呢?结构是一样的,它支持 Typescript。我们可以注意到一个区别:class 而不是 className(它也支持条件类)。

在事件监听方面,SolidJS 非常接近 DOM 事件。我们可以通过添加 on 作为前缀来监听原始事件。看一下如何在上面的代码片段中捕获 mousemove 事件。

在更深入地探索这个库时,你会注意到其他一些小的差异,但总的来说,我们是否可以同意它看起来与 React 几乎相同?


状态管理

有几种方法可以管理 React 应用程序中的状态。您可以使用 useState 或 useReducer 在本地执行此操作,也可以在组件树的分支中实现上下文。作为外包解决方案,您可以使用 Redux 或 Mobx 等状态管理库。

我的目标不是为这些解决方案辩护,而是向您展示 SolidJS 如何实现它们。


在组件级别

import { render } from "solid-js/web";import { Component, createSignal } from "solid-js";const Counter: Component = () => {  const [count, setCount] = createSignal(0);    setInterval(() => setCount(count() + 1), 1000);  const doubleCount = () => count() * 2;  return Count: {count()} - Double Count: {doubleCount()};}render(() => , document.getElementById('app'));

我们从 React 中知道的 useState 在 SolidJS 中变成了 createSignal。 要访问状态的值,我们需要调用它。

也可以创建派生信号,就像我们使用 doubleCount 一样。 通过访问组件状态,派生值将通过触发依赖于它们的任何效果来携带它们的反应性。

与 React 和我们期望的 useState 行为不同,计数状态不仅仅是一个数字。 它是一个返回一个数字的函数,通过调用这个函数,我们最终订阅了那个值。


useMemo 与 createMemo

React 中的 useMemo 就像缓存最后一个结果一样简单,直到正在监视的值发生变化。

使用 Solid 的 createMemo,事情会变得简单一些。

import { render } from 'solid-js/web';import { createSignal, createMemo } from 'solid-js';function fibonacci(num) {  if (num <= 1) return 1;  return fibonacci(num - 1) + fibonacci(num - 2);}function Counter() {  const [count, setCount] = createSignal(10);  const fib = createMemo(() => fibonacci(count()));  return (    <>            {fib()}      );}render(() => , document.getElementById('app'))

无需观察计数值的变化。 由于 count 实际上是一个提供订阅的函数,因此 createMemo 函数会与它建立联系。 createMemo 返回的值也是一个函数,所以我们需要在需要使用它的值时调用它。


全局状态

有时只做本地状态管理会导致一团糟,对吗? 为了避免过多的属性钻取,SolidJD 有一个超级简单的解决方案。 由于我们正在处理信号的概念,我们可以简单地提取所有本地信号,并在 store.ts 文件中声明它们。

import { createSignal, createResource } from "solid-js";import { createMutable } from "solid-js/store";export const list = createMutable({  items: JSON.parse(    window.localStorage.getItem("cart") ?? "[]"  ),  get count() {    return this.items.length;  },  addItem(item) {    this.products.push(item);  },  clear() {    this.items = [];  },});export const [count, setCount] = createSignal(0);export const [items] = createResource(  () => fetch("your api ...").then((res) => res.json()),  {    initialValue: [],  });

这有多好?! 这有多简单?! 真的,这太神奇了。 你只需要声明你的状态,导出它们,无论你在哪里使用它们,都会进行订阅!

这种方法开启了多种不同的策略。 你可以做一个全局商店,你可以做一些局部商店,你可以组合商店。 这就是自由!


控制流

在我们的应用程序开发过程中,我们永远不会摆脱一种结构:列表。 在使用 React 时,我们通常通过简单地创建一个映射并返回 JSX 来做到这一点。 在 React 中,我们需要担心将唯一值传递给 key 属性,因此当单个元素更改时,React 不必重新渲染整个列表。

SolidJs 使用 For 标签的方式稍有不同:

import { render } from 'solid-js/web';import { Component } from 'solid-js';import { createSignal, For } from 'solid-js';const App: Component = () => {  const [cats, setCats] = createSignal([    { id: 'J---aiyznGQ', name: 'Keyboard Cat' },    { id: 'z_AbfPXTKms', name: 'Maru' },    { id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }  ]);    return (      );}render(() => , document.getElementById('app'))

Solid 方法的好处是我们不需要担心键和性能。 列表中的索引 (i) 也是一个信号。 因此,该列表订阅了索引,并且当发生更改时,Solid 知道确切的更新位置。

除此之外,SolidJS 还提供了另一种呈现列表的选项:Index 标签。 如果您正在迭代的值是基元,它会提高性能。


路线

如果你使用 react-router-dom 在你的 React 应用程序上实现路由,我必须说你在这里几乎没有工作要做。 只需将其替换为 solid-app-router ! (有一点不同:一个 Link 组件将有一个属性 href 而不是 to )

import { lazy } from "solid-js";import { Routes, Route, Link } from "solid-app-router"const Users = lazy(() => import("./pages/Users"));const Home = lazy(() => import("./pages/Home"));export default function App() {  return <>    

My Site with Lots of Pages

}

学习新的框架/库或技术可能具有挑战性。 如果我们可以选择重新使用我们的知识并在我们的列表中增加一项技能,那就更好了。 SolidJS 非常有效地做到了这一点,尤其是对于 React 开发人员。

您是否想了解为什么 SolidJS 如此之快? 好吧,它没有使用 Virtual DOM,而是使用细粒度的响应式解决方案,将模板直接编译到 dom 中。


关注七爪网,获取更多APP/小程序/网站源码资源!

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章