A React compatibility layer for Preact
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Support for legacy React patterns including createClass, DOM factories, and deprecated lifecycle methods for backward compatibility.
Legacy React component creation using the createClass pattern.
/**
* Create component class using legacy React pattern
* @param {object} spec - Component specification object
* @returns {ComponentClass} Component constructor
*/
function createClass(spec);
/**
* Component specification for createClass
*/
interface ComponentSpec {
// Required render method
render(): VNode;
// Optional lifecycle methods
getInitialState?(): object;
getDefaultProps?(): object;
componentWillMount?(): void;
componentDidMount?(): void;
componentWillReceiveProps?(nextProps: object): void;
shouldComponentUpdate?(nextProps: object, nextState: object): boolean;
componentWillUpdate?(nextProps: object, nextState: object): void;
componentDidUpdate?(prevProps: object, prevState: object): void;
componentWillUnmount?(): void;
// Mixins support
mixins?: Array<object>;
// Auto-binding
[methodName: string]: any;
}Usage Examples:
import { createClass } from 'preact-compat';
// or
import createClass from 'preact-compat/lib/create-react-class';
const MyComponent = createClass({
getInitialState() {
return { count: 0 };
},
getDefaultProps() {
return { title: 'Default Title' };
},
handleClick() {
this.setState({ count: this.state.count + 1 });
},
render() {
return (
<div>
<h1>{this.props.title}</h1>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
});Factory functions for creating HTML elements without JSX.
/**
* DOM element factories for all HTML elements
*/
const DOM = {
// Common elements
a: ElementFactory<AnchorHTMLAttributes>;
div: ElementFactory<HTMLAttributes>;
span: ElementFactory<HTMLAttributes>;
p: ElementFactory<HTMLAttributes>;
h1: ElementFactory<HTMLAttributes>;
h2: ElementFactory<HTMLAttributes>;
h3: ElementFactory<HTMLAttributes>;
h4: ElementFactory<HTMLAttributes>;
h5: ElementFactory<HTMLAttributes>;
h6: ElementFactory<HTMLAttributes>;
// Form elements
form: ElementFactory<FormHTMLAttributes>;
input: ElementFactory<InputHTMLAttributes>;
button: ElementFactory<ButtonHTMLAttributes>;
select: ElementFactory<SelectHTMLAttributes>;
option: ElementFactory<OptionHTMLAttributes>;
textarea: ElementFactory<TextareaHTMLAttributes>;
label: ElementFactory<LabelHTMLAttributes>;
// Media elements
img: ElementFactory<ImgHTMLAttributes>;
video: ElementFactory<VideoHTMLAttributes>;
audio: ElementFactory<AudioHTMLAttributes>;
// Table elements
table: ElementFactory<TableHTMLAttributes>;
thead: ElementFactory<HTMLAttributes>;
tbody: ElementFactory<HTMLAttributes>;
tr: ElementFactory<HTMLAttributes>;
td: ElementFactory<TdHTMLAttributes>;
th: ElementFactory<ThHTMLAttributes>;
// ... and all other HTML elements
};
/**
* Element factory function type
*/
interface ElementFactory<P = {}> {
(props?: P, ...children: ComponentChildren[]): VNode;
}Usage Examples:
import { DOM } from 'preact-compat';
// or
import { DOM } from 'preact-compat/lib/react-dom-factories';
// Create elements without JSX
const element = DOM.div(
{ className: 'container', id: 'main' },
DOM.h1(null, 'Hello World'),
DOM.p(null, 'This is a paragraph'),
DOM.button(
{ onClick: handleClick },
'Click me'
)
);
// Equivalent JSX:
// <div className="container" id="main">
// <h1>Hello World</h1>
// <p>This is a paragraph</p>
// <button onClick={handleClick}>Click me</button>
// </div>import { createClass } from 'preact-compat';
// Example mixin
const TimerMixin = {
componentWillMount() {
this.timers = [];
},
componentWillUnmount() {
this.timers.forEach(clearInterval);
},
setInterval(fn, delay) {
const id = setInterval(fn, delay);
this.timers.push(id);
return id;
}
};
const MyComponent = createClass({
mixins: [TimerMixin],
getInitialState() {
return { seconds: 0 };
},
componentDidMount() {
this.setInterval(() => {
this.setState({ seconds: this.state.seconds + 1 });
}, 1000);
},
render() {
return <div>Seconds: {this.state.seconds}</div>;
}
});Legacy PropTypes support (re-exported from prop-types).
/**
* PropTypes for runtime type checking (re-exported from prop-types package)
*/
const PropTypes = {
array: Validator<any[]>;
bool: Validator<boolean>;
func: Validator<Function>;
number: Validator<number>;
object: Validator<object>;
string: Validator<string>;
symbol: Validator<symbol>;
node: Validator<ComponentChildren>;
element: Validator<VNode>;
instanceOf(expectedClass: any): Validator<any>;
oneOf(expectedValues: any[]): Validator<any>;
oneOfType(expectedTypes: Validator<any>[]): Validator<any>;
arrayOf(expectedType: Validator<any>): Validator<any[]>;
objectOf(expectedType: Validator<any>): Validator<object>;
shape(expectedShape: ValidationMap<any>): Validator<object>;
exact(expectedShape: ValidationMap<any>): Validator<object>;
// Modifiers
isRequired: symbol;
};
interface ValidationMap<T> {
[K in keyof T]?: Validator<T[K]>;
}
interface Validator<T> {
(props: object, propName: string, componentName: string): Error | null;
isRequired: Validator<T>;
}Usage Examples:
import { PropTypes } from 'preact-compat';
const MyComponent = createClass({
propTypes: {
name: PropTypes.string.isRequired,
age: PropTypes.number,
items: PropTypes.arrayOf(PropTypes.string),
user: PropTypes.shape({
id: PropTypes.number.isRequired,
email: PropTypes.string
}),
onClick: PropTypes.func
},
getDefaultProps() {
return {
age: 0,
items: []
};
},
render() {
return (
<div onClick={this.props.onClick}>
<h1>{this.props.name}</h1>
<p>Age: {this.props.age}</p>
</div>
);
}
});// Main imports
import { createClass, DOM, PropTypes } from 'preact-compat';
// Specific library imports
import createClass from 'preact-compat/lib/create-react-class';
import { DOM } from 'preact-compat/lib/react-dom-factories';
// CommonJS
const { createClass, DOM, PropTypes } = require('preact-compat');interface CreateClassSpec {
render(): VNode;
getInitialState?(): object;
getDefaultProps?(): object;
mixins?: Array<object>;
[key: string]: any;
}
type CreateClassComponent = ComponentClass<any>;
interface DOMFactory<P = {}> {
(props?: P, ...children: ComponentChildren[]): VNode;
}
interface DOMFactories {
[elementName: string]: DOMFactory;
}Install with Tessl CLI
npx tessl i tessl/npm-preact-compat