https://github.com/mcjazzyfunky/archived-preactive
An alternative API for programming components and hook function with Preact
https://github.com/mcjazzyfunky/archived-preactive
hooks preact preact-components
Last synced: about 1 month ago
JSON representation
An alternative API for programming components and hook function with Preact
- Host: GitHub
- URL: https://github.com/mcjazzyfunky/archived-preactive
- Owner: mcjazzyfunky
- License: unlicense
- Created: 2019-12-19T20:23:42.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-11T17:52:35.000Z (over 3 years ago)
- Last Synced: 2025-10-11T06:05:26.715Z (8 months ago)
- Topics: hooks, preact, preact-components
- Language: JavaScript
- Homepage:
- Size: 1.04 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 21
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Preactive
A R&D project to evaluate an alternative API for developing
components and hook functions with Preact.
The main advantages of the new API are:
- 0% magic
- Does not make any trouble for the garbage collector
- No rules of hooks
- No special linter necessary
- 100% accurately typeable - in the function type signature
of hook functions or function that generate hook functions etc.,
it will always be visible what we are dealing with.
### Installation
```
git clone https://github.com/mcjazzyfunky/preactive.git
cd preactive
npm install
```
### Running demos
```
npm run storybook
```
## Examples
### Stateless components (variant 1)
```jsx
import { h, render } from 'preact'
import { statelessComponent } from 'preactive'
const HelloWorld = statelessComponent('HelloWorld', props => {
return (
{props.salutation || 'Hello'}, {props.name || 'world'}
)
})
```
### Stateless components (variant 2)
```jsx
import { h, render } from 'preact'
import { statelessComponent } from 'preactive'
const HelloWorld = statelessComponent('HelloWorld', ({
salutation = 'Hello',
name = 'world'
}) => {
return (
{props.salutation}, {props.name}
)
})
```
### Stateless components (variant 3)
```jsx
import { h, render } from 'preact'
import { statelessComponent } from 'preactive'
const HelloWorld = statelessComponent({
displayName: 'HelloWorld',
defaultProps: {
salutation: 'Hello',
name: 'world'
}
}, props => {
return (
{props.salutation}, {props.name}
)
})
```
### Stateless components (variant 4)
```jsx
import { h, render } from 'preact'
import { statelessComponent } from 'preactive'
const HelloWorld = statelessComponent({
displayName: 'HelloWorld',
defaultProps: {
salutation: 'Hello',
name: 'world'
},
render: renderHelloWorld
}
function renderHelloWorld(props) {
return (
{props.salutation}, {props.name}
)
}
```
### Stateful components (variant 1)
```jsx
import { h, render } from 'preact'
import { statefulComponent, useValue } from 'preactive'
const Counter = statefulComponent('Counter', (c, props) => {
const
[count, setCount] = useValue(c, props.initialValue || 0),
onIncrement = () => setCount(it => it + 1)
return () =>
{props.label || 'Counter'}:
{count.value}
})
render(, document.getElementById('app'))
```
### Stateful components (variant 2)
```jsx
import { h, render } from 'preact'
import { statefulComponent, useValue } from 'preactive'
const Counter = statefulComponent({
displayName: 'Counter',
memoize: true,
defaultProps: {
initialValue: 0,
label: 'Counter'
}
}, (c, props) => {
const
[count, setCount] = useValue(c, props.initialValue),
onIncrement = () => setCount(it => it + 1)
return () =>
{props.label}:
{count.value}
})
render(, document.getElementById('app'))
```
### Stateful components (variant 3)
```jsx
import { h, render } from 'preact'
import { statefulComponent, useValue } from 'preactive'
const Counter = statefulComponent({
displayName: 'Counter',
memoize: true,
defaultProps: {
initialValue: 0,
label: 'Counter'
},
init: initCounter
})
function initCounter(c, props) {
const
[count, setCount] = useValue(c, props.initialValue),
onIncrement = () => setCount(it => it + 1)
return () =>
{props.label}:
{count.value}
})
render(, document.getElementById('app'))
```
In the above examples the `c` is a so called component controller
(some kind of representation for the component instance).
The type of the component controller is currently the following
(please be aware that "normal" developers will never have to use these
methods directly they will only be used internally by some basic
hook and utility functions):
```typescript
type Ctrl = {
isMounted(): boolean,
update(): void,
getContextValue(Context): T,
afterMount(subscriber: Subscriber): void,
beforeUpdate(subscriber: Subscriber): void,
afterUpdate(subscriber: Subscriber): void,
beforeUnmount(subscriber: Subscriber): void,
runOnceBeforeUpdate(task: Task): void
}
type Props = Record
type Subscriber = () => void
type Task = () => void
type Context = Preact.Context
```
## API
### Component definition
- `statelessComponent(displayName, render: props => vnode)`
- `statelessComponent(meta, render: props => vnode)`
- `statelessComponent(config)`
- `statefulComponent(displayName, init: c => props => vnode)`
- `statefulComponent(meta, init: c => props => vnode)`
- `statefulComponent(config)`
### Utility functions
- `isMounted(c)`
- `forceUpdate(c)`
- `asRef(valueOrRef)`
- `toRef(getter)`
### Hooks
- `useValue(c, initialValue)`
- `useState(c, initialStateObject)`
- `useContext(c, context)`
- `useMemo(c, calculation, () => dependencies)`
- `useEffect(c, action, () => dependencies)`
- `useInterval(c, action, milliseconds)`
## Project state
This R&D project is still in a very early development state