What is @lit-labs/react?
@lit-labs/react is an npm package that provides utilities for integrating Lit components with React. It allows developers to use Lit-based web components seamlessly within React applications.
What are @lit-labs/react's main functionalities?
Creating React Components from Lit Elements
This feature allows you to create React components from Lit elements. The `createComponent` function takes React, the tag name of the custom element, and the Lit element class, and returns a React component that can be used in your React application.
import { createComponent } from '@lit-labs/react';
import * as React from 'react';
import { MyElement } from 'my-element';
const MyReactComponent = createComponent(React, 'my-element', MyElement);
export default MyReactComponent;
Passing Properties and Events
This feature allows you to pass properties and events from React to Lit elements. The fourth argument to `createComponent` is an object that maps React props to Lit element properties and events.
import { createComponent } from '@lit-labs/react';
import * as React from 'react';
import { MyElement } from 'my-element';
const MyReactComponent = createComponent(React, 'my-element', MyElement, {
onClick: 'click',
onCustomEvent: 'custom-event'
});
export default MyReactComponent;
Other packages similar to @lit-labs/react
react-web-component
The `react-web-component` package allows you to create web components from React components. It provides a way to use React components as custom elements, which can then be used in any web application. Unlike @lit-labs/react, which focuses on integrating Lit elements into React, `react-web-component` focuses on the opposite direction.
reactify-wc
The `reactify-wc` package is another utility for integrating web components with React. It provides a higher-order component (HOC) that wraps a web component and makes it usable in React. This package is similar to @lit-labs/react but offers a different API for achieving the same goal.
@lit-labs/react
React integration for Web Components and Reactive Controllers.
Overview
createComponent
While React can render Web Components, it cannot
easily pass React props to custom element properties or event listeners.
This package provides a utility wrapper createComponent
which makes a
React component wrapper for a custom element class. The wrapper correctly
passes React props
to properties accepted by the custom element and listens
for events dispatched by the custom element.
How it works
For properties, the wrapper interrogates the web component class to discover
its available properties. Then any React props
passed with property names are
set on the custom element as properties and not attributes.
For events, createComponent
accepts a mapping of React event prop names
to events fired by the custom element. For example passing {onfoo: 'foo'}
means a function passed via a prop
named onfoo
will be called when the
custom element fires the foo event with the event as an argument.
Usage
Import React
, a custom element class, and createComponent
.
import * as React from 'react';
import {createComponent} from '@lit-labs/react';
import {MyElement} from './my-element.js';
export const MyElementComponent = createComponent(
React,
'my-element',
MyElement,
{
onactivate: 'activate',
onchange: 'change',
}
);
After defining the React component, you can use it just as you would any other
React component.
<MyElementComponent
active={isActive}
onactivate={(e) => (isActive = e.active)}
/>
useController
Reactive Controllers allow developers to hook a component's lifecycle to bundle
together state and behavior related to a feature. They are similar to React
hooks in the user cases and capabilities, but are plain JavaScript objects
instead of functions with hidden state.
useController
is a React hook that create and stores a Reactive Controller
and drives its lifecycle using React hooks like useState
and
useLayoutEffect
.
How it works
useController
uses useState
to create and store an instance of a controller and a ReactControllerHost
. It then calls the controller's lifecycle from the hook body and useLayoutEffect
callbacks, emulating the ReactiveElement
lifecycle as closely as possible. ReactControllerHost
implements addController
so that controller composition works and nested controller lifecycles are called correctly. ReactControllerHost
also implements requestUpdate
by calling a useState
setter, so that a controller with new renderable state can cause its host component to re-render.
Controller timings are implemented as follows:
Controller API | React hook equivalent |
---|
constructor | useState initial value |
hostConnected | useState initial value |
hostDisconnected | useLayoutEffect cleanup, empty deps |
hostUpdate | hook body |
hostUpdated | useLayoutEffect |
requestUpdate | useState setter |
updateComplete | useLayoutEffect |
Usage
import * as React from 'react';
import {useController} from '@lit-labs/react/use-controller.js';
import {MouseController} from '@example/mouse-controller';
const useMouse = () => {
const controller = useController(React, (host) => new MouseController(host));
return controller.position;
};
const Component = (props) => {
const mousePosition = useMouse();
return (
<pre>
x: {mousePosition.x}
y: {mousePosition.y}
</pre>
);
};
Installation
From inside your project folder, run:
$ npm install @lit-labs/react
Contributing
Please see CONTRIBUTING.md.