Inferno

repository·master·Indexed 12 days ago

https://github.com/infernojs/inferno

An extremely high-performance, React-like library for building user interfaces, optimized for real-time data and large DOM trees. The ecosystem includes inferno-animation for CSS animations, inferno-compat for React compatibility, inferno-clone-vnode for virtual node cloning, and inferno-create-element for element creation.

Tokens
60.8K
Snippets
200
Records
265
Agent score
96%

What's inside Inferno

  1. What is Inferno?

    master
    Inferno is a high-performance, React-like library designed for building fast user interfaces on both the client and server. It focuses on providing the fastest possible runtime performance, making it ideal for applications rendering real-time data views or large DOM trees. It uses a component-driven architecture with one-way data flow and supports both class and functional components.
  2. What is inferno-compat and when to use it

    master

    inferno-compat is a compatibility layer designed to make React-based modules work with Inferno without requiring code changes. It provides the same exports as react and react-dom, allowing you to use build tool aliasing to swap React for Inferno.

    Important Considerations:

    • Performance: There is an associated overhead; you should not expect native Inferno performance when using this layer.
    • Scope: You might not always need the full inferno-compat package; sometimes a simple alias to inferno is sufficient. If you need specific features like createElement support, you must also install the corresponding package (e.g., inferno-create-element).
  3. Define Class and Functional Components

    master

    Inferno supports two primary ways to define components:

    1. Class Components: Extend the Component class from inferno and implement a render() method.
    2. Functional Components: Standard JavaScript functions where the first argument is props.

    Functional components can also use defaultProps and defaultHooks (e.g., onComponentShouldUpdate).

    // Class Component
    import { Component } from 'inferno';
    class MyComponent extends Component {
      render() {
          return <div>My Component</div>
      }
    }
    
    // Functional Component
    const MyComponent = ({ name, age }) => (
      <span>My name is: { name } and my age is: {age}</span>
    );
    
    // Functional Component with defaultProps
    export function MyFunctionalComponent({value}) {
        return <div>{value}</div>;
    }
    MyFunctionalComponent.defaultProps = {
        value: 10
    };
  4. Async data fetching with the loader attribute

    master

    inferno-router supports async data fetching before navigation using the loader attribute on a Route. This allows you to fetch necessary data before the component is rendered. You can then access this data within the component using the useLoaderData hook.

    Example usage:

    <Route
      path="/about"
      component={About}
      loader={() => fetch(new URL('/api/about', BACKEND_HOST))}
    />
  5. Use Fragments to render multiple elements without a container

    master

    Fragments allow you to return an array of elements from a component's render method, creating an invisible layer that groups content without adding an extra DOM node.

    Syntax Options:

    • Short syntax: <> ... </> (requires babel-plugin-inferno)
    • Long syntax: <Fragment> ... </Fragment> or <Inferno.Fragment> ... </Inferno.Fragment> (allows specifying key for dynamic lists)
    • API: createFragment(children, childFlags, key)
    • createElement: createElement(Inferno.Fragment, {key: 'test'}, ...children)
    • hyperscript: h(Inferno.Fragment, {key: 'test'}, children)
    import { Component, Fragment } from 'inferno';
    
    class MyApplication extends Component {
        render() {
            return (
                <>
                    <span id="hi">Hi</span>
                    <div id="okay">Okay</div>
                </>
            );
        }
    }
    
    // Long syntax with keys for dynamic lists
    class ListApp extends Component {
        render() {
            const list = [
                <Fragment key="coffee">
                    <dt>Coffee</dt>
                    <dd>Black hot drink</dd>
                </Fragment/>
            ];
            return <dl>{list}</dl>;
        }
    }
  6. Implement Controlled Components

    master

    In Inferno, mutable state should typically be kept in the component's state property and updated via setState().

    A controlled component is a form element (like <input>, <textarea>, or <select>) where the Inferno component's state acts as the single source of truth for the element's value, preventing the DOM from holding independent state.

  7. Use new Component lifecycle methods

    master

    Inferno v6 introduces lifecycle methods compatible with React. When using these new methods, the older lifecycle methods (componentWillMount, componentWillReceiveProps, componentWillUpdate) will not be called.

    New methods:

    • getDerivedStateFromProps
    • getSnapshotBeforeUpdate

    Note: Inferno does not use UNSAFE_ prefixes; use the standard method names.

  8. How global animations work

    master

    Global animations allow you to animate a component between two different "pages" (where the elements do not share the same parent).

    When one page is mounted immediately after another is unmounted, inferno-animation performs a FLIP-animation between the two positions. To enable this, assign the same string value to the globalAnimationKey attribute on both elements.

  9. Understand Inferno's event system

    master

    Inferno uses a partially synthetic event system that delegates specific events for better performance.

    Key differences from React:

    • Inferno does not rename events by default. While React uses onChange, Inferno uses the native DOM event name (e.g., onInput).
    • Events should be camel cased. Lower case events will bypass Inferno's system and use the native browser event system.

    Supported synthetic events:

    • onClick, onDblClick
    • onFocusIn, onFocusOut
    • onKeyDown, onKeyPress, onKeyUp
    • onMouseDown, onMouseMove, onMouseUp
    • onTouchEnd, onTouchMove, onTouchStart
  10. Comparison with React-Router

    master

    If you are coming from react-router, note the following differences in inferno-router:

    • No React Native support: Unlike react-router, inferno-router does not provide official support for React Native.
    • Unified Package: There is no separate inferno-router-dom package; all web-related routing functionality is contained within inferno-router.
    • Feature Parity: It is a port of react-router v4/v5, with added support for the loader attribute (from v6) for async data fetching.
    • Missing Features: Currently, inferno-router does not support download progress, form submission, or redirect support (in the sense of exposing response headers/status to the render method).
  11. V6 VNode property changes

    master

    Several internal VNode properties have changed or been removed in v6:

    • dom property: Not always populated for Components or Fragments. Use findDOMNode from inferno-extras instead.
    • parentVNode: This property has been removed.
    • Text children: For optimization, single text children are no longer wrapped in another VNode. The children property of a VNode containing only text will now hold the string directly (e.g., vNode.children === 'Hello').