Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/micha-lmxt/hooks-as-store
https://github.com/micha-lmxt/hooks-as-store
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/micha-lmxt/hooks-as-store
- Owner: micha-lmxt
- License: mit
- Created: 2022-10-28T14:19:54.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2023-01-24T19:54:44.000Z (almost 2 years ago)
- Last Synced: 2024-09-29T12:05:32.630Z (3 months ago)
- Language: TypeScript
- Size: 105 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# hooks-as-store
Use React custom hooks in Svelte Apps.
[hooks-as-store page](https://hooks-as-store.gradientdescent.de)
## Installation
```bash
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:
```javascript
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:
```javascript
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:```javascript
$: ({ 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.:```javascript
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:```javascript
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:```javascript
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':
```javascript
...
const config: UserConfig = {
...
resolve:{
alias:{
react:'hooks-as-store'
}
},
...
}
...
```For aliases on other bundlers I found this page helpful: [Switching to Preact](https://preactjs.com/guide/v8/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':```json
{
"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':
```javascript
...
{
...
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](https://github.com/sammdec/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 strategyThe 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!