CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-preact-compat

A React compatibility layer for Preact

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

refs-system.mddocs/

Refs System

Reference system for accessing DOM nodes and component instances directly.

Capabilities

Create Ref

Creates ref objects for accessing DOM nodes and component instances.

/**
 * Create a ref object for accessing DOM nodes or component instances
 * @returns {RefObject} Ref object with current property
 */
function createRef();

/**
 * Ref object interface
 */
interface RefObject<T> {
  /**
   * Current reference value (DOM node or component instance)
   */
  current: T | null;
}

Usage Examples:

import { createRef, Component } from 'preact-compat';

class InputComponent extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }
  
  focusInput = () => {
    if (this.inputRef.current) {
      this.inputRef.current.focus();
    }
  };
  
  componentDidMount() {
    // Access DOM node directly
    console.log(this.inputRef.current); // <input> element
  }
  
  render() {
    return (
      <div>
        <input ref={this.inputRef} type="text" />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

Callback Refs

Alternative ref pattern using callback functions.

/**
 * Callback ref function
 * @param {Element|Component|null} instance - DOM node or component instance
 */
type RefCallback<T> = (instance: T | null) => void;

Usage Examples:

import { Component } from 'preact-compat';

class CallbackRefComponent extends Component {
  inputElement = null;
  
  setInputRef = (element) => {
    this.inputElement = element;
  };
  
  focusInput = () => {
    if (this.inputElement) {
      this.inputElement.focus();
    }
  };
  
  render() {
    return (
      <div>
        <input ref={this.setInputRef} type="text" />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

Forwarding Refs

Pattern for passing refs through component boundaries.

import { createRef, cloneElement } from 'preact-compat';

// Higher-order component that forwards refs
function withForwardedRef(WrappedComponent) {
  return function ForwardedRefComponent(props) {
    const { forwardedRef, ...otherProps } = props;
    return <WrappedComponent ref={forwardedRef} {...otherProps} />;
  };
}

// Usage
class MyInput extends Component {
  focus() {
    this.inputRef.current.focus();
  }
  
  render() {
    return <input ref={this.inputRef} {...this.props} />;
  }
}

const ForwardedInput = withForwardedRef(MyInput);

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.childRef = createRef();
  }
  
  handleClick = () => {
    this.childRef.current.focus();
  };
  
  render() {
    return (
      <div>
        <ForwardedInput forwardedRef={this.childRef} />
        <button onClick={this.handleClick}>Focus Child</button>
      </div>
    );
  }
}

Refs with Functional Components

Using refs in functional components (note: hooks not available in preact-compat 3.19.0).

import { createRef } from 'preact-compat';

// Ref passed as prop
function FunctionalInput({ inputRef, ...props }) {
  return <input ref={inputRef} {...props} />;
}

// Usage
class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }
  
  render() {
    return (
      <FunctionalInput 
        inputRef={this.inputRef}
        placeholder="Type here..."
      />
    );
  }
}

Common Ref Patterns

import { createRef, Component } from 'preact-compat';

class RefPatternsExample extends Component {
  constructor(props) {
    super(props);
    
    // Multiple refs
    this.formRef = createRef();
    this.inputRefs = {
      username: createRef(),
      password: createRef(),
      email: createRef()
    };
    
    // Dynamic refs array
    this.itemRefs = [];
  }
  
  // Create refs for dynamic list
  setItemRef = (index) => (element) => {
    this.itemRefs[index] = element;
  };
  
  // Scroll to specific item
  scrollToItem = (index) => {
    if (this.itemRefs[index]) {
      this.itemRefs[index].scrollIntoView({ behavior: 'smooth' });
    }
  };
  
  // Form submission
  handleSubmit = (e) => {
    e.preventDefault();
    const form = this.formRef.current;
    const formData = new FormData(form);
    
    // Validate inputs
    Object.values(this.inputRefs).forEach(ref => {
      if (ref.current && !ref.current.value) {
        ref.current.focus();
        return;
      }
    });
  };
  
  render() {
    const items = ['Item 1', 'Item 2', 'Item 3'];
    
    return (
      <div>
        <form ref={this.formRef} onSubmit={this.handleSubmit}>
          <input 
            ref={this.inputRefs.username}
            name="username" 
            placeholder="Username" 
          />
          <input 
            ref={this.inputRefs.password}
            name="password" 
            type="password"
            placeholder="Password" 
          />
          <input 
            ref={this.inputRefs.email}
            name="email" 
            type="email"
            placeholder="Email" 
          />
          <button type="submit">Submit</button>
        </form>
        
        {items.map((item, index) => (
          <div 
            key={index}
            ref={this.setItemRef(index)}
            onClick={() => this.scrollToItem(index)}
          >
            {item}
          </div>
        ))}
      </div>
    );
  }
}

Types

interface RefObject<T> {
  current: T | null;
}

type RefCallback<T> = (instance: T | null) => void;

type Ref<T> = RefCallback<T> | RefObject<T>;

// Common ref types
type DOMRef = Ref<HTMLElement>;
type InputRef = Ref<HTMLInputElement>;
type FormRef = Ref<HTMLFormElement>;
type ComponentRef<T extends Component> = Ref<T>;

Install with Tessl CLI

npx tessl i tessl/npm-preact-compat

docs

children-utilities.md

context-api.md

core-api.md

immutability-helpers.md

index.md

legacy-apis.md

performance-tools.md

refs-system.md

server-rendering.md

transition-groups.md

tile.json