React Multi Email Input Component
`react-multi-email` is a lightweight and dependency-free React component designed for creating an input field that can manage and format multiple email addresses as a user types. Currently stable at version `1.0.25`, the library maintains a moderate release cadence, addressing bugs and adding new features such as improved handling of duplicate emails (case-insensitive) and an `inputValue` prop. Its core differentiators include a minimalist codebase, small bundle size, and straightforward customization options, allowing developers to easily integrate a robust multi-email input without significant overhead. It supports both synchronous and asynchronous email validation and offers custom label rendering for each email, making it a flexible choice for forms requiring multiple email entries.
Common errors
-
Module not found: Can't resolve 'react-multi-email/dist/style.css' in 'path/to/your/component'
cause The bundler cannot locate the CSS file required for the component's styling.fixVerify that `react-multi-email` is correctly installed. Ensure the path `react-multi-email/dist/style.css` is accessible and that your build setup correctly handles CSS imports. -
TypeError: (0 , react_multi_email__WEBPACK_IMPORTED_MODULE_1__.ReactMultiEmail) is not a function
cause This error typically occurs when attempting to use a CommonJS `require()` statement or an incorrect default import for `ReactMultiEmail` in an ESM context, or vice-versa.fixUse a named import: `import { ReactMultiEmail } from 'react-multi-email';` for ESM environments. If using CommonJS, ensure `const { ReactMultiEmail } = require('react-multi-email');` is used, though the library primarily targets modern React setups with ESM. -
Emails are entered into the input field but do not format into distinct styled 'tags' or chips.
cause The component's essential stylesheet (`style.css`) is not being loaded or applied, resulting in a lack of visual styling for the email tags.fixConfirm that `import 'react-multi-email/dist/style.css';` is present and correctly imported into your application. Check your browser's developer tools to see if the stylesheet is loaded and if its styles are being applied or overridden.
Warnings
- gotcha The component requires a separate CSS import (`import 'react-multi-email/dist/style.css';`) for correct visual rendering. Without this import, the email tags will appear unstyled and potentially misaligned, impacting the user interface.
- gotcha Prior to version `1.0.25`, users reported an issue where the loading spinner might not stop if the `validateEmail` prop, when returning a Promise, failed to resolve successfully. This could leave the UI in a perpetual loading state for invalid asynchronous validations.
- gotcha The `inputValue` prop was added in `v1.0.25` to provide external control over the input field's current value. While this offers greater flexibility, be mindful that introducing external control over an input can sometimes lead to unexpected side effects if not managed carefully, especially in existing codebases that might have relied on internal state for the input field.
Install
-
npm install react-multi-email -
yarn add react-multi-email -
pnpm add react-multi-email
Imports
- ReactMultiEmail
import ReactMultiEmail from 'react-multi-email'; const ReactMultiEmail = require('react-multi-email');import { ReactMultiEmail } from 'react-multi-email'; - isEmail
const isEmail = require('react-multi-email').isEmail;import { isEmail } from 'react-multi-email'; - Component Stylesheet
import 'react-multi-email/dist/style.css';
Quickstart
import * as React from 'react';
import { ReactMultiEmail, isEmail } from 'react-multi-email';
import 'react-multi-email/dist/style.css';
function BasicExample() {
const [emails, setEmails] = React.useState<string[]>([]);
const [focused, setFocused] = React.useState(false);
return (
<form>
<h3>Email Input</h3>
<ReactMultiEmail
placeholder='Input your email addresses'
emails={emails}
onChange={(_emails: string[]) => {
setEmails(_emails);
}}
autoFocus={true}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
validateEmail={email => isEmail(email)}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>
<br />
<h4>Current Emails:</h4>
<p>{emails.join(', ') || 'empty'}</p>
<h3>Input Focused: {focused ? 'true' : 'false'}</h3>
</form>
);
}
export default BasicExample;