Meet React to Web Component (R2WC) v2
Tags: react, webcomponents, opensource, javascript
Published: 2023-06-06 15:03:00

Greetings, dev community! The highly-anticipated release of the new R2WC ([react-to-web-component](https://www.bitovi.com/open-source/react-to-web-component)) API is here! We have been thrilled by the level of adoption version 1.0 has attained within the developer community. You have provided great feedback in our [Discord](https://discord.gg/J7ejFsZnJ4) and [GitHub issues](https://github.com/bitovi/react-to-web-component/issues) on your pain points and the ways in which we can improve R2WC. And we listened!

## What is R2WC?

[React to Web Component] (https://www.bitovi.com/open-source/r2wc) is the best way to encapsulate React components into standalone Web Components. It lets you use React anywhere! React to Web Component is especially useful for microfrontends and dropping React code into otherwise static sites. 

Gone are the days of redeveloping components for the web. Now you can wrap any component from your React component library and use it in any project that uses HTML, regardless of its framework or library. 

## Updates and New Features
Let’s get to the good stuff! Check out the new features in [R2WC v2](https://github.com/bitovi/react-to-web-component).

- TypeScript Support
- Simplified API
- Improved Syncing
- New npm Namespace
- Continued Support for React 16, 17, and 18

### TypeScript Support
We are elated to announce that R2WC has full TypeScript support! TypeScript has cemented itself as a staple in the dev community thanks to its enhanced type safety. Now you’ll be able to see warnings and make changes to your React components accordingly. 

![Image showing TypeScript in use in React to Web Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bshew73xs3p5k0dyd0v6.png)

### Simplified API
In R2WC v1, you had to pass in an instance of React and ReactDOM to the function call. Not anymore! We have added React and ReactDOM as peer dependencies for R2WC, with support for v16, 17, and 18 for React and ReactDOM. Now you can get started using R2WC even faster. 

Here’s how calling R2WC worked in v1:
```javascript
import React from "react"
import ReactDOM from "react-dom/client" // if using React 18
// import ReactDOM from "react-dom" // if using React 17

import r2wc from "react-to-webcomponent"

const WebGreeting = r2wc(Greeting, React, ReactDOM)

customElements.define("web-greeting", WebGreeting)
```
And here's how calling R2WC works in v2! It's that simple:
```
import r2wc from "@r2wc/react-to-web-component"

const WebGreeting = r2wc(Greeting)

customElements.define("web-greeting", WebGreeting)
```
### Improved Syncing
One of the most common issues reported to us about R2WC version 1.0 is that props were not being accepted by the created web component in production. This is because propTypes are generally removed from a React project when it is built for production.

We are happy to announce that the internal functionality of R2WC no longer depends on propTypes! Instead, we have given you two ways to pass props to R2WC—as an array of prop names as strings or an object with key-value pairs being your prop names and their corresponding types.

```javascript
import r2wc from '@r2wc/react-to-web-component'

type GreetingProps = {
  name: string;
}

const Greeting: FC<GreetingProps> = ({ name }) => {
  return <h2> Hello, { name } </h2>;
}


// Recommended
const GreetingWebComponent = r2wc(Greeting, { props: { name: "string" }})

// OR for simpler needs
/*
const GreetingWebComponent = r2wc(Greeting, { props: ["name"] })
*/

customElements.define('greeting-wc', GreetingWebComponent)
```
R2WC now takes two parameters—a `ReactComponent` and an `options` object. The `options` object has two keys - `shadow` and `props`. The shadow key can be one of two values - `“open" | "closed"` - while the props key can either be an array of strings representing your prop names or an object with key-value pairs of your props and their types.

**Note:** If the `props` option is passed in as an array of prop names, R2WC will treat all these props as `strings`. If passed in as an object, the keys represent the names of your props (camel cased), and the values can be one of `"string" | "number" | "boolean" | "function" | "json"`.

Here's an example of how the new `props` option works in R2WC v2:

```javascript
import r2wc from '@r2wc/react-to-web-component'

type ListProps = {
  title: string
  items: string[]
}

const SimpleList: FC<ListProps> = ({ title, items }) => {
  return (
    <>
      <h3>{title}</h3>
      <ul>
        {items.map((item) => {
          return <li>{item}</li> 
        })}
      </ul>
    </>
  )
}

const ListWC = r2wc(SimpleList, { 
    props: { title: "string", items: "json" }, 
    shadow: "open"
  })

customElements.define("my-list", ListWC);

/* in your index.html */

<my-list title="hobbies" items="['swimming', 'coding', 'reading blogs']"></my-list> 
```
### New npm Namespace
The new version of R2WC lives in a [new namespace on npm](https://www.npmjs.com/package/@r2wc/react-to-web-component) called `'@r2wc/react-to-web-component'` and utilizes another package called `'@r2wc/core'`, which contains the meat of the functionality for the new version.

Our legacy version will still live in the namespace `'react-to-webcomponent'` on npm and will also receive an update to utilize the new core. This means that it will also receive TypeScript support, freedom from propType issues, and benefit from the new syncing mechanism between attributes, properties, and props. However, to avoid breaking your current codebase, the legacy `'react-to-webcomponent'` package will still take React and ReactDOM as parameters. See type definition below.

```javascript
function r2wc<Props>(ReactComponent: React.ComponentType<Props>, React: ReactType, ReactDOM: ReactDOMRootType | ReactDOMRenderType, options?: R2WCOptions<Props>): CustomElementConstructor
```
### Continued Support for React 16, 17, and 18
The new R2WC API from `'@r2wc/react-to-web-component'` will support the current version of React (v18 as of the writing of this article) and versions 16 and 17. 

Our new package has been released in two versions. If you’re using React 16 or 17, you should use v1, `'react-to-webcomponent'`. This version utilizes React’s older rendering API for mounting your `ReactComponent` to the web component. 

If you’re on React 18, you can use v2 namespace `'@r2wc/react-to-web-component'` and utilize React’s newer mounting mechanism of first creating a `root` container that then renders the `ReactComponent`.

## Try React to Web Component yourself!
We are excited to have you all start using our new API and look forward to your feedback. Head on over to our [CodeSandbox](https://codesandbox.io/s/checklist-r2wc-example-y3nqwx) to play with R2WC. Happy coding! 😁

### What do you think?
Drop into our [Community Discord](https://discord.gg/J7ejFsZnJ4) and let us know what you think of [React to Web Component](https://www.bitovi.com/open-source/react-to-web-component) v2. We’d love to hear your thoughts, help you troubleshoot, and see what you’re working on!