An extremely fast, React-like JavaScript library for building modern user interfaces
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Reference system for accessing DOM elements and component instances, with forward ref support for passing refs through component boundaries.
Creates a ref object for accessing DOM elements or component instances.
/**
* Creates a ref object for accessing DOM elements or component instances
* @returns RefObject with current property initially set to null
*/
function createRef<T = Element>(): RefObject<T>;
interface RefObject<T> {
readonly current: T | null;
}Usage Examples:
import { createRef, Component, createVNode, VNodeFlags } from "inferno";
class TextInputComponent extends Component {
constructor(props) {
super(props);
this.inputRef = createRef<HTMLInputElement>();
}
focusInput = () => {
if (this.inputRef.current) {
this.inputRef.current.focus();
}
};
componentDidMount() {
// Access DOM element after mount
if (this.inputRef.current) {
console.log('Input element:', this.inputRef.current);
}
}
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
ref: this.inputRef,
type: 'text',
placeholder: 'Enter text'
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Focus Input', ChildFlags.HasInvalidChildren, {
onClick: this.focusInput
})
]);
}
}Creates a component that forwards refs to child components or DOM elements.
/**
* Creates a component that forwards refs to child components or DOM elements
* @param render - Render function that receives props and ref
* @returns Component that can accept and forward refs
*/
function forwardRef<T = any, P = Props<any>>(
render: (
props: Readonly<{ children?: InfernoNode }> & Readonly<P>,
ref: RefObject<T>
) => InfernoNode
): any;Usage Examples:
import { forwardRef, createRef, createVNode, VNodeFlags } from "inferno";
// Forward ref component for custom input
const CustomInput = forwardRef<HTMLInputElement, { placeholder?: string }>((props, ref) => {
return createVNode(VNodeFlags.InputElement, 'input', 'custom-input', null, ChildFlags.HasInvalidChildren, {
ref: ref,
type: 'text',
placeholder: props.placeholder
});
});
class ParentComponent extends Component {
constructor(props) {
super(props);
this.customInputRef = createRef<HTMLInputElement>();
}
handleClick = () => {
if (this.customInputRef.current) {
this.customInputRef.current.focus();
this.customInputRef.current.value = 'Focused!';
}
};
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createComponentVNode(VNodeFlags.ForwardRefComponent, CustomInput, {
ref: this.customInputRef,
placeholder: 'Custom input'
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Focus Custom Input', ChildFlags.HasInvalidChildren, {
onClick: this.handleClick
})
]);
}
}Internal function for mounting refs (used by the rendering system).
/**
* Internal function for mounting refs during the rendering process
* @param ref - Ref callback or RefObject
* @param value - Value to assign to the ref
* @param lifecycle - Array of lifecycle functions to execute
*/
function mountRef(ref: any, value: any, lifecycle: Array<() => void>): void;Internal function for unmounting refs (used by the rendering system).
/**
* Internal function for unmounting refs during component cleanup
* @param ref - Ref callback or RefObject to unmount
*/
function unmountRef(ref: any): void;type Ref<T = Element> = {
bivarianceHack(instance: T | null): any;
}['bivarianceHack'];interface ForwardRef<P, T> extends Inferno.StatelessComponent<P> {
ref: Ref<T>;
}class ScrollableComponent extends Component {
constructor(props) {
super(props);
this.containerRef = createRef<HTMLDivElement>();
}
scrollToTop = () => {
if (this.containerRef.current) {
this.containerRef.current.scrollTop = 0;
}
};
scrollToBottom = () => {
if (this.containerRef.current) {
this.containerRef.current.scrollTop = this.containerRef.current.scrollHeight;
}
};
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createVNode(VNodeFlags.HtmlElement, 'div', 'scrollable', this.props.children, ChildFlags.UnknownChildren, {
ref: this.containerRef,
style: { height: '200px', overflow: 'auto' }
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Scroll to Top', ChildFlags.HasInvalidChildren, {
onClick: this.scrollToTop
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Scroll to Bottom', ChildFlags.HasInvalidChildren, {
onClick: this.scrollToBottom
})
]);
}
}class ChildComponent extends Component {
getValue() {
return this.state.value;
}
reset() {
this.setState({ value: '' });
}
render() {
return createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
value: this.state.value,
onChange: (e) => this.setState({ value: e.target.value })
});
}
}
class ParentComponent extends Component {
constructor(props) {
super(props);
this.childRef = createRef<ChildComponent>();
}
handleGetValue = () => {
if (this.childRef.current) {
console.log('Child value:', this.childRef.current.getValue());
}
};
handleReset = () => {
if (this.childRef.current) {
this.childRef.current.reset();
}
};
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createComponentVNode(VNodeFlags.ComponentClass, ChildComponent, {
ref: this.childRef
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Get Value', ChildFlags.HasInvalidChildren, {
onClick: this.handleGetValue
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Reset', ChildFlags.HasInvalidChildren, {
onClick: this.handleReset
})
]);
}
}class CallbackRefComponent extends Component {
setInputRef = (element: HTMLInputElement | null) => {
this.inputElement = element;
if (element) {
console.log('Input element mounted:', element);
} else {
console.log('Input element unmounted');
}
};
focusInput = () => {
if (this.inputElement) {
this.inputElement.focus();
}
};
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
ref: this.setInputRef,
type: 'text'
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Focus', ChildFlags.HasInvalidChildren, {
onClick: this.focusInput
})
]);
}
}class MultiRefComponent extends Component {
constructor(props) {
super(props);
this.refs = {
input1: createRef<HTMLInputElement>(),
input2: createRef<HTMLInputElement>(),
container: createRef<HTMLDivElement>()
};
}
focusFirst = () => {
this.refs.input1.current?.focus();
};
focusSecond = () => {
this.refs.input2.current?.focus();
};
getAllValues = () => {
const values = {
input1: this.refs.input1.current?.value || '',
input2: this.refs.input2.current?.value || ''
};
console.log('All values:', values);
return values;
};
render() {
return createVNode(VNodeFlags.HtmlElement, 'div', null, [
createVNode(VNodeFlags.HtmlElement, 'div', 'input-container', [
createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
ref: this.refs.input1,
placeholder: 'Input 1'
}),
createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
ref: this.refs.input2,
placeholder: 'Input 2'
})
], ChildFlags.HasNonKeyedChildren, {
ref: this.refs.container
}),
createVNode(VNodeFlags.HtmlElement, 'div', null, [
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Focus First', ChildFlags.HasInvalidChildren, {
onClick: this.focusFirst
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Focus Second', ChildFlags.HasInvalidChildren, {
onClick: this.focusSecond
}),
createVNode(VNodeFlags.HtmlElement, 'button', null, 'Get Values', ChildFlags.HasInvalidChildren, {
onClick: this.getAllValues
})
], ChildFlags.HasNonKeyedChildren)
]);
}
}function withLogging<P>(WrappedComponent: any) {
return forwardRef<any, P>((props, ref) => {
console.log('Rendering with props:', props);
return createComponentVNode(
VNodeFlags.ComponentClass,
WrappedComponent,
{ ...props, ref }
);
});
}
const LoggedInput = withLogging(CustomInput);const InputGroup = forwardRef<HTMLInputElement, { label: string; placeholder?: string }>((props, ref) => {
return createVNode(VNodeFlags.HtmlElement, 'div', 'input-group', [
createVNode(VNodeFlags.HtmlElement, 'label', null, props.label),
createVNode(VNodeFlags.InputElement, 'input', null, null, ChildFlags.HasInvalidChildren, {
ref: ref,
placeholder: props.placeholder
})
]);
});