Web Components
React 和 Web Component 是為了解決不同的問題所建立的。Web Component 為了可重複使用的 component 提供了強大的封裝,而 React 提供了一個宣告式函式庫,使 DOM 與你的資料保持同步。這兩個目標是相輔相成的。作為開發人員,你可以自由地在 Web Component 中使用 React,或在 React 中使用 Web Component,或兩者都是。
大部分使用 React 的人沒有使用 Web Component,但你可能會想要使用,尤其是你用到了使用 Web Component 所寫的第三方的 UI component。
在 React 裡使用 Web Component
class HelloMessage extends React.Component {
render() {
return <div>Hello <x-search>{this.props.name}</x-search>!</div>;
}
}
注意:
Web Component 通常會公開命令式的 API。例如,一個
video
Web Component 可能會公開play()
和pause()
函式。為了能夠使用 Web Component 的命令式 API,你會需要使用 ref 來跟 DOM 節點直接互動。如果你使用第三方的 Web Component,最好的解法是寫一個 React component 來包住你的 Web Component。Web Component 所發出的事件可能不會被正確的傳遞到 React 的 render tree。 你將會需要手動把 event handler 附加到你的 React component 內處理這些事件。
一個常見的疑惑是 Web Component 使用「class」而不是「className」。
function BrickFlipbox() {
return (
<brick-flipbox class="demo">
<div>front</div>
<div>back</div>
</brick-flipbox>
);
}
在你的 Web Component 裡使用 React
class XSearch extends HTMLElement {
connectedCallback() {
const mountPoint = document.createElement('span');
this.attachShadow({ mode: 'open' }).appendChild(mountPoint);
const name = this.getAttribute('name');
const url = 'https://www.google.com/search?q=' + encodeURIComponent(name);
const root = ReactDOM.createRoot(mountPoint);
root.render(<a href={url}>{name}</a>);
}
}
customElements.define('x-search', XSearch);
注意:
如果你用 Babel 轉換了 class,這段程式碼將不會正常運作。查看這個 issue 裡面的討論。 在載入 web component 之前引入 custom-elements-es5-adapter 來解決這個問題。