PreffX is a self-confident JS library for creating reactive DOM. It is inspired by React and Preact, but offers its own signal-based approach.
- React-like JSX syntax;
- Preact signals as reactivity core;
- only signals cause rerender;
- each component is executed only once;
- component props come as the first argument and all utilities come as the second argument - there is no need to import them,
- both sync and async function components support;
- distinction between properties and attributes (all properties are prefixed with
$) - for example,$valueis a property, andvalueis an attribute.
Try Vite + PreffX demo
- Simple counter:
import type { PC } from 'preffx';
export const App: PC = (props, { signal }) => {
const count = signal(0);
return <button
onClick={() => {
count.value += 1
}}
>
Count is {count}
</button>
};- How to create element refs:
import type { PC } from 'preffx';
export const App: PC = (props, { signal }) => {
const signalRef = signal();
return <div $ref={signalRef}>
<div
$ref={(refVal) => {
// it will be called after element mounted with refVal = HTMLDivElement
// and before element destroyed with refVal = null
}}
>
Refs
</button>
</div>
};- Lifecycle hooks:
import type { PC } from 'preffx';
export const App: PC = (props, { onMount, onDestroy }) => {
const count = signal(0);
onMount(() => {
// some mount logic
});
onDestroy(() => {
// some destroy logic
});
return <button
onClick={() => {
count.value += 1
}}
>
Count is {count}
</button>
};- List rendering:
import type { PC } from 'preffx';
export const App: PC = (props, { For }) => {
const items = signal([
{
name: 'First'
},
{
name: 'Second'
}
]);
return <ul>
<For
items={items}
callback={(item) => <li>Item with name: {item.name}</li>}
fallback={<li>No items</li>}
/>
</ul>;
};- Context handling:
import type { PC } from 'preffx';
import { AnotherComponent } from './components';
export const App: PC = (props, { context }) => {
// get value from context
const valueFromContext = context.someValue;
// add value for children context
context.forChild = 'Another value';
return <p>
{valueFromContext}
<AnotherComponent />
</p>;
};- Async components:
import type { APC } from 'preffx';
import { getData } from './data';
import { AnotherComponent, AnotherAsyncComponent } from './components';
const AsyncComponent: APC<{
name: string;
}> = async (props, utils) => {
const data = await getData()
const componentRoot = await <AnotherAsyncComponent name='nested'/>;
return <div>
<AnotherComponent data={data} />
{componentRoot}
</div>;
}- Error handling:
import type { PC } from 'preffx';
import { AnotherComponent } from './components';
export const App: PC = (props, { Catch }) => {
return <div>
Sometimes components return errors
<Catch fallback={<div>Catched!</div>}>
<AnotherComponent />
</Catch>
</div>;
};