Skip to main content

3 posts tagged with "React"

View All Tags

Web Components in React

· One min read

Open in Notion

Events of Web Components in React

An improvement would be to extract the event listener callback function in order to remove the listener when the component unmounts.

import React from 'react';

import 'road-dropdown';

const Dropdown = ({ label, option, options, onChange }) => {
const ref = React.useRef();

React.useLayoutEffect(() => {
const handleChange = customEvent => onChange(customEvent.detail);

const { current } = ref;

current.addEventListener('onChange', handleChange);

// returning the callback in order to remove the listener when the component unmounts.
return () => current.removeEventListener('onChange', handleChange);
}, [ref]);

return (
<road-dropdown
ref={ref}
label={label}
option={option}
options={JSON.stringify(options)}
/>
);
};
That's it for adding an event listener for

React to Web Components

Below works with the useCustomElement React Hook which can be installed via npm install use-custom-element:

import React from 'react';

import 'road-dropdown';

import useCustomElement from 'use-custom-element';

const Dropdown = props => {
const [customElementProps, ref] = useCustomElement(props);

return <road-dropdown {...customElementProps} ref={ref} />;
};

Package your React Component for distribution via NPM

· 2 min read

Open in Notion

1. MAKE A PACKAGE NPM PUBLISHABLE

npm init

In the package.json, make sure these fields are populated: package.json

{
"name": "myUnflappableComponent",
"version": "0.0.29",
"main": "dist/index.js",
"publishConfig": {
"access": "restricted"
},
...
}

2. DON’T BUNDLE REACT. USE THE PARENT’S REACT AND REACT-DOM.

In package.json, add React and react-dom in the project’s peerDependencies (And remove it from dependencies, but add it to devDependencies for development)

...
"peerDependencies": {
"react": "&gt;=15.0.1",
"react-dom": "&gt;=15.0.1"
},
"devDependencies": {
"react": "&gt;=15.0.1",
"react-dom": "&gt;=15.0.1"
},
...

In your webpack configuration, create a UMD bundle

...
module.exports = {
...
output: {
path: path.join(__dirname, './dist'),
filename: 'myUnflappableComponent.js',
library: libraryName,
libraryTarget: 'umd',
publicPath: '/dist/',
umdNamedDefine: true
},
plugins: {...},
module: {...},
resolve: {...},
externals: {...}
}

And super-duper important, don’t bundle React

module.exports = {
output: {...},
plugins: {...},
module: {...},
resolve: {
alias: {
'react': path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
}
},
externals: {
// Don't bundle react or react-dom
react: {
commonjs: "react",
commonjs2: "react",
amd: "React",
root: "React"
},
"react-dom": {
commonjs: "react-dom",
commonjs2: "react-dom",
amd: "ReactDOM",
root: "ReactDOM"
}
}
}

3. SET UP YOUR .NPMIGNORE FILE

If you don’t set up a .npmignore file, npm uses your .gitignore file and bad things will happen. An empty .npmignore file is allowed. This is what mine looks like:

webpack.local.config.js

webpack.production.config.js .eslintrc .gitignore