npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fane_the_divine/react-signal

v0.0.3

Published

在react中使用signal

Readme

react-signal

在react里使用signal

API参考solid,使用方法见demo.

npm包

npm i @fane_the_divine/react-signal

使用时可能出现hmr失效的问题,需要重建组件或刷新网页

API介绍

createSignal

创建signal

const [count, setCount] = createSignal(0)

// 使用signal
count()

// 不具有响应性地获取signal里的值
count.value

可以在任何位置使用createSignal

defineComponent

type CompProps = {
  num: () => number
}
const Comp = defineComponent<CompProps>((props) => {
  // props对象是signal 参数也是signal
  return () => <span>{props().num()}</span>
})

defineComponent接受一个setup函数 这个函数在组件整个生命周期内只执行一次 setup应当返回一个render函数 这个函数会执行多次

createMemo

创建一个派生signal

// 参数为上一次的memo值
const double = createMemo((prev) => {
  return count() * 2
})

// 访问其值
double()

// 不具有响应性地获取其值
double.value

可以在任何位置使用createMemo
派生signal会记录当前值是否过期 直到值被访问的时候才实际进行计算

createEffect

创建基于signal的副作用,它们在react的useEffect阶段执行

defineComponent(() => {
  createEffect(
    // 允许effect函数返回一个值 并会输入到下一次effect函数
    // 可以从参数判断是否第一次调用
    (prev, isFirst) => {
      // 以非.value方式使用的signal会被收集 在其变化后 触发副作用
      signal1()
      return (prev ?? 0) + 1
    },
    // 允许提供一个signal数组作为额外的依赖
    [signal2],
    {
      // 在useLayoutEffect阶段执行副作用
      layoutEffect: true,
    },
  )
})

createEffect应当在defineComponent内部调用
关于它的清理函数 参考下一节

onCleanup

提供清理函数

defineComponent(() => {
  createMemo(() => {
    onCleanup(() => console.log('memo cleanup'))
  })
  createEffect(() => {
    onCleanup(() => console.log('effect cleanup'))
  })
  onCleanup(() => console.log('component cleanup'))
})

onCleanup可以在defineComponent createMemo createEffect内部调用 作用不同

  • 在defineComponent内调用时 cleanup函数在组件销毁后调用
  • createEffect/createMemo内调用时 cleanup会在effect/memo函数调用前调用

createRef

创建一个react ref

defineComponent(() => {
  const spanRef = createRef<HTMLSpanElement>()
  return () => <span ref={spanRef} />
})

不提供参数时 类型是RefObject<T|null> 可以直接用到html上

实现原理简述

reactivity.ts定义了响应式作用域组件作用域相关内容.

通过全局变量的方式,可以注册一个响应式作用域。在它内部使用的signal变化后,响应式作用域可以感知这一变化并做出反应。例如组件会更新,派生signal将自身标记为已过期等。响应式作用域还可以感知内部的onCleanup调用,收集清理函数,并在自身销毁时调用清理函数。

组件作用域同样通过全局变量实现,它可以让函数在本组件的下一次useEffect阶段调用被调用.

defineComponent会创建响应式作用域和组件作用域。它会收集setup函数中的onCleanup调用,以及render函数中对signal的使用。

createMemo会创建响应式作用域。它不会立刻调用memo函数,而是在signal()signal.value时才实际计算值。在memo函数执行后,它会收集其使用到的signal,每次memo函数执行前都会清空上次收集的signal。在其依赖的signal变化后,它将自身标记为已过期,并向所有使用自身的响应式作用域发消息。

createEffect在依赖收集方面与createMemo类似。在副作用实现上,createEffect确保函数callEffectFn在每个useEffect都执行。这个函数会访问shouldCallEffect变量,它为true时再执行effect函数,然后将此变量置为false。每当createEffect包裹的signal变化时,shouldCallEffect被置为true。

onCleanup获取当前的响应式作用域并将增加其清理函数。

createRef返回了一个普通对象。