SolidJs的基础教程

376 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

这是学习SolidJs学习的第二天,直接上手API了。

Signal

signal是响应式的基本要素。 首先我们需要从solid-js库导入createSignal函数,同时在组件中调用。 用一段代码说明:

import { createSignal, onCleanup } from "solid-js";
import { render } from "solid-js/web";

const CountingComponent = () => {
	const [count, setCount] = createSignal(0);
	const interval = setInterval(
		() => setCount(c => c + 1),
		1000
	);
	onCleanup(() => clearInterval(interval));
	return <div>Count value is {count()}</div>;
};

render(() => <CountingComponent />, document.getElementById("app"));

CountingComponent组件中创建一个count变量名的响应式变量,定义一个循环定时器,每一秒之后将count变量加一。

image.png

可以看出在没有外部作用下,自动将变化的数据渲染到页面上。

Effect

上面我们说到signal是一个响应式要素,包括createSignal是创建一个响应式数据的函数,相当于是输入,而Effect是一个输出,它会追踪响应式数据,响应式数据发生变化,就会观察到并同时触发该函数。

import { render } from 'solid-js/web';
import { createSignal, createEffect } from 'solid-js';

function Counter() {
  const [count, setCount] = createSignal(0);
  createEffect(() => { console.log("The count is now", count()); });
  return <button >Click Me</button>;
}

render(() => <Counter />, document.getElementById('app'))

这个示例也比较简单,点击按钮重新设置count值,由于signal被该改变了,便会触发createEffect函数。

#衍生Signal signal是包装可跟踪值的简单的getter函数,而衍生Signal是什么呢,只要在其它函数函数中使用到了signal,都可定义为siganl并且也是可追踪的。

Memo

衍生signal是可追踪的,但是只要响应式数据发生变化都会触发,就是没有缓存作用。而Memo就是有缓存作用的衍生signal,用来存储和访问最后一个缓存的值,而无需重新进行求值,直到它们依赖关系发生变化时才重新求值。 需要从solid-js库导入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(() => {
    console.log('Calculating Fibonacci');
    return fibonacci(count());
  });

  return (
    <>
      <button onClick={() => setCount(count() + 1)}>Count: {count()}</button>
      <div>1. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>2. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>3. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>4. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>5. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>6. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>7. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>8. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>9. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
      <div>10. {fib()} {fib()} {fib()} {fib()} {fib()}</div>
    </>
  );
}

render(() => <Counter />, document.getElementById('app'))

代码也比较简单,就是求斐波拉数。在页面上有个按钮,点击按钮会改变signal值,而在createMemo依赖于signal值,触发时,重新计算一次,同时将最后一次数据缓存起来,每次点击只会重新计算一次。