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 🙏

© 2024 – Pkg Stats / Ryan Hefner

hooks-as-store

v0.3.0

Published

Use React custom hooks in Svelte Apps.

Downloads

2

Readme

hooks-as-store

Use React custom hooks in Svelte Apps.

hooks-as-store page

Installation

npm install --save-dev hooks-as-store

Usage

Let's say you have some custom hook code in 'myhook.js', which calles built-in hooks or other custom hooks:

import {useState, useEffect} from 'hooks-as-store';

export const myHook = (someprop,otherprop)=>{

    const [value,setValue] = useState(someprop);

    useEffect(()=>{
       ...
    },[otherprop]);

    return {value, setValue}
}

In svelte script part you can load this hook like this:

import { hook } from 'hooks-as-store';
import { myHook } from './myhook';

const hookStore = hook(myHook, 'someprop', 'abc');

First argument to the hook function is the custom hook you want to execute. You can pass props to the hook in the following arguments. Call the hook function in a non-reactive script part of a component (do not use $:). Never call the hook function inside a custom hook. hookStore is a readable store. If you want to access its values, you can unload it like this:

$: ({ value, setValue } = $hookStore);

Notice the autosubscription ($hookstore) and the brackets around the whole statement.

The hook is automatically re-run, when a state inside is changed, e.g. when setValue is used.

You can re-execute the hook code with the run propery, eg. myHook.run(props). It does not automatically re-run, whenever the component is updated. If you want this behavior (like it is in React), you need to implement it yourself, eg.:

import {beforeUpdate} from 'svelte';
...
beforeUpdate(()=>{
    myHook.run("someprop", "abc")
})

If that is really necessary depends on your use-case. Often it may be enough to re-execute it when the props change:

let prop1 = 'someprop',
	prop2 = 'abc';
$: myHook.run(prop1, prop2);

Dependend hooks

If you have more than one custom hooks, which depend on each other, it might be useful to group them. The function hookGroup accepts an array of arrays. In the inner array, the first element should be the hook, the rest is filled with the props for this hook. Eg:

import { hoogGroup } from 'hooks-as-store';
import { hook1, hook2, hook3 } from './myhooks.';

const hookResults = hookGroup([
	[hook1, hook1prop1, hook1prop2], //hook1 takes 2 props
	[hook2], //hook2 doesn't take props
	[hook3, hook3props]
]);
// unwrap hookResults
$: [
	{ hook1returnvalue },
	undefined /*hook2 does not return anything*/,
	{ hook3returnvalue1, hook3returnvalue2 }
] = $hookResults;

// re-execute all hooks if any prop changes
$: hookResults.run([hook1prop1, hook1prop2], [], [hook3props]);

Once a state changes in any of the three hooks, all hooks are re-executed in the same order.

Extenal hooks

You can redirect the imports from 'react' to 'hooks-as-store' like this in 'vite.config.js':

...
const config: UserConfig = {
	...
	resolve:{
		alias:{
			react:'hooks-as-store'
		}
	},
    ...
}
...

For aliases on other bundlers I found this page helpful: Switching to Preact

If React errors occur (Invalid hook call. Hooks can only be called inside of the body of a function component. etc.), try deleting the 'react' folder in 'node_modules'. Another option, which seems to be more persistent, is to go into node_modules/react/package.json and change 'main':

{
	"main": "../hooks-as-store/index.js"
}

To also change the imports in external libraries, it might be necessary to mark these libraries as noExternal in 'vite.config.js':

...
{
    ...
    ssr:{
		noExternal:["use-media","@wellyshen/use-web-animations"]
	}
}
...

Notes

Most of the built-in react hooks are implemented in this package, but not all are tested very well.

Context

The useContext hook makes use of Svelte contexts. If you can set the context with 'setContext' from 'svelte', it works. Some libraries offers custom provider components, eg. use-cart. This case is not yet usable with this library.

Contribution

Contributions are welcome. Some topics of interest:

  • good examples for uncommon hooks (eg. useId, useDeferredValue, useImperativeHandle etc.)
  • better/easier 'alias' strategy for imported react hooks / better vite configuration
  • Context strategy

The scope of this library is to enable the use of custom react hooks. It can be referenced as part of a general react interop library, but it is not planned to become one itself.

To expand this idea, you could say that a React functional component is a custom hook, which returns a part of a virtual dom tree. You could (easily?) implement a createElement function, obtain the tree from this library and create a generic svelte virtual dom tree renderer component. Something like this is not in the scope of this library, but let me know if you try it!