React
对于使用 create-react-app
脚本构建的应用程序,包含组件库的最简单方法是从
index.js
文件调用defineCustomElements()
。请注意,在这种情况下,如果您的目标是 Edge 或 IE11,则需要
applyPolyfills
。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
// test-component is the name of our made up Web Component that we have
// published to npm:
import { applyPolyfills, defineCustomElements } from 'test-components/loader';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
applyPolyfills().then(() => {
defineCustomElements();
});
遵循上述步骤将使您的 Web 组件能够在 React 中使用,但是还必须考虑一些额外的复杂性。https://custom-elements-everywhere.com/ 包含当前问题的概要。
属性和事件
React 目前在使用标准 HTML 自定义元素时最大的缺陷是包含非标量数据(即不是字符串或数字的数据)的属性没有正确传递,自定义事件没有正确处理。 这两个问题的解决方案是将自定义元素包装在一个 React 组件中,获取自定义元素的
ref
,并使用 ref
来设置非标量属性并通过
addEventListener 添加事件监听器
。 这是一个示例,展示了它如何用于属性传递:
import React, { useRef, useEffect } from 'react';
import { Forecast } from '../models';
import { iconPaths } from '../util';
const DailyForecast: React.FC<{ forecast: Forecast; scale: string }> = ({ forecast, scale }) => {
const elementRef = useRef(null);
useEffect(() => {
(elementRef.current as any)!.iconPaths = iconPaths;
(elementRef.current as any)!.forecasts = forecast;
}, [forecast]);
return <kws-daily-forecast scale={scale} ref={elementRef}></kws-daily-forecast>;
};
export default DailyForecast;
在这个例子中,有三个属性:forecast
是一个对象数组,iconPaths
是一个对象,而 scale
是一个字符串。 由于
scale
是一个字符串,所以可以正常处理。 但是,其他两个属性是非标量的,必须通过
ref
设置为自定义元素。 像这样包装自定义元素可以防止您必须为您可能需要的每个
kws-daily-forecast
实例获取
ref
,因为您将改为使用 DailyForecast
React 组件:
<DailyForecast scale={scale} forecast={f}></DailyForecast>
绑定
在 React 组件中手动包装所有自定义元素是一种很好的做法,但很快就会变得乏味。 使用 Stencil 的绑定功能,基于 Stencil 的 Web 组件被包装在一个 React 组件中,使它们可以立即作为 React 组件使用。
Stencil 的 React 绑定修复了 React 的 Web 组件支持的主要问题,包括无法正确传递属性。开箱即用,React 只能将字符串和数字传递给组件,而不能侦听自定义事件。通过绑定,所有属性都可以正确传递,包括函数、对象和数组。绑定还通过创建一个名为“onprop
来处理自定义事件。最后,包含类型,使代码更可靠且更易于重构。这些特性允许 React 开发人员与 Web 组件交互,就好像它们是 React 组件一样。
起步
如果您要将 Stencil 组件编译为多个框架库,建议创建一个包含 Stencil 库和每个框架库的 monorepo 项目,以便于维护。 完整的参考项目见stencil-ds-plugins-demo。
在这个例子中,component-library
是一个 Stencil 库,component-library-react
是一个 React 库,其中将生成基于 Stencil 的 React 组件。
创建一个 monorepo 目录,然后将任何现有的 Stencil 组件存储库移动到 monorepo 项目中:
mkdir component-mono
mv component-library component-mono/component-library
React 组件库设置
首先,我们需要设置包含 Stencil 生成的 React 组件的 React 库。您可以创建自己的 React 项目结构或使用 Stencil React template repo 来引导它。建议这个 repo 作为你的 Stencil 组件库的兄弟,所以在 Stencil monorepo 中,克隆项目:
git clone https://github.com/ionic-team/stencil-ds-react-template
在 package.json
中,如果你已经在 npm 上发布了 Stencil 库,请将
component-library
依赖项名称更改为你的库名称,然后运行
npm install
。
如果未在 npm 上发布任何库和/或您想在本地构建和测试,请删除 component-library
依赖项。接下来,切换到 Stencil 库目录并运行
npm link
。改回 React 库并运行
npm link <library>
,其中
library
是您的 Stencil 库名称。最后,运行
npm install
。
Stencil Config 设置
配置基本的 React 库后,下一步是配置 Stencil 以输出 React 组件。切换到您的 Stencil 组件库目录,然后安装 React 输出目标:
npm install @stencil/react-output-target --save-dev
接下来,打开 stencil.config.ts
然后将 React 添加到输出目标列表中:
import { Config } from '@stencil/core';
import { reactOutputTarget } from '@stencil/react-output-target';
export const config: Config = {
namespace: 'demo',
outputTargets: [
reactOutputTarget({
componentCorePackage: 'component-library',
proxiesFile: '../component-library-react/src/components.ts',
includeDefineCustomElements: true,
}),
{
type: 'dist',
},
],
};
componentCorePackage
这是您的核心 Stencil 库的包名称,其中仅包含在 npm 上发布的 Web 组件。这个包被 React 包作为依赖项引用。例如,Ionic Framework 的核心库是@ionic/core
,是@ionic/react
的一个依赖。
proxiesFile
这是由 outputTarget 生成的输出文件。此文件应引用不同的包位置。在这里的 monorepo 示例中,我们选择了同级目录的 src 目录 - stencil-ds-react-template - 包名为component-library-react
。在 Stencil 构建期间,会创建一个 React 包,该包导出此文件中定义的所有组件。
includeDefineCustomElements
在此处指定 true(推荐)意味着使用 React 应用程序不必手动导入和调用
index.js
中的
defineCustomElements()
。
配置 React 支持后,运行 npm run build
来创建 Stencil React 绑定。您将在
component-library-react
的 dist 文件夹中看到新生成的文件。
接下来,将目录更改为 stencil-ds-react-template
然后安装依赖项并构建项目:
npm install
npm run build
如果需要,可以在 npm 上发布 React 库,然后将其添加为项目依赖项。
如果你不想在 npm 上发布库、或者你想在 React 应用程序中本地构建和测试它,请使用 npm link
链接项目,然后将目录更改为你的 React 应用程序并运行
npm link component-library-react
。
用法
由于 Stencil 生成的 React 库实际上是一个常规的 React 库,因此可以像使用任何 React 库一样使用它。 从包中导入组件:
import { DemoComponent } from 'component-library-react';
Contributors
Thanks for your interest!
We just need some basic information so we can send the guide your way.