To handle the onPaste
event on a React element, set its onPaste
prop to an event handler. You can get the pasted text from the handler using event.clipboardData.getData('text')
.
For example:
import React, { useState } from 'react';
export default function App() {
const [pasted, setPasted] = useState('');
const handlePaste = (event) => {
setPasted(event.clipboardData.getData('text'));
};
return (
<div>
<input placeholder="Message" onPaste={handlePaste} type="text" id="message" />
<br />
You pasted: <b>{pasted}</b>
</div>
);
}
The function (event listener) passed to the onPaste
prop is called when the user pastes text into the input field.
The event
object has various properties and methods used to get more info and take actions concerned with the event.
For the paste
event, event
has a clipboardData
property that stores the data stored on the clipboard.
getData()
gives us the data in the clipboard in a particular format. We pass 'text'
as the first argument to get text data.
For the purposes of our example, we create a state that’ll be updated to the latest text data pasted in the input field. We display this text to the user.
Note: We used the useState
hook to manage the state. This hook returns an array of two values, where the first is a variable that stores the state, and the second is a function that updates the state when it is called.
Handle onPaste event in entire window
To handle the paste event on the entire document window in React, set a paste
event handler on the window
object with addEventListener()
:
import React, { useState, useEffect } from 'react';
export default function App() {
const [pasted, setPasted] = useState('');
useEffect(() => {
const handlePaste = (event) => {
setPasted(event.clipboardData.getData('text'));
}
window.addEventListener('paste', handlePaste)
return () => {
window.removeEventListener('paste', handlePaste)
};
})
return (
<div>
Pasted: <b>{pasted}</b>
<br />
<input placeholder="Message" type="text" id="message" />
<br />
<input placeholder="Sender" type="text" id="sender" />
</div>
);
}
The addEventListener()
method takes up to two arguments:
type
: a string representing the event type to listen for.'paste'
is for a paste event.listener
: the function called when the event fires.
It also takes some optional arguments, which you can learn more about here.
We call addEventListener()
in the useEffect
hook to register the listener once the component renders as the page loads. We pass an empty dependencies array to useEffect
so this registration happens only once. In the cleanup function, we call the removeEventListener()
method to unregister the event listener and prevent a memory leak.
As we saw earlier, the event
object has many methods and properties that let us get more info and take event-related actions.
For the paste
event, event
has a clipboardData
property that contains the data stored on the clipboard.
The clipboard.getData()
is the clipboard data in a specific format. Like before, we pass 'text'
as the first argument to get text data.
Get clipboard data without paste
We may not want to wait for the user to do a paste before getting the clipboard data. In a case like this, the clipboard.readText()
method from the navigator
object helps:
import React, { useState } from 'react';
export default function App() {
const [pasted, setPasted] = useState('');
const handlePaste = async (_event) => {
const clipboardText = await navigator.clipboard.readText();
setPasted(clipboardText);
}
return (
<div>
Pasted: <b>{pasted}</b><br />
<button onClick={handlePaste}>Paste</button>
</div>
);
}
Here we wait for a click
before getting the text in the clipboard.
readText()
is an async method, so we await
it in an async
event handler to get the Promise
‘s result.
Note
Before the browser can read clipboard data, it’ll show the user a dialog to grant permission first:
Prevent onPaste
event in React
Like for many other events, we can prevent the default UI action of the paste
event with event.preventDefault()
in the handler:
import React, { useState, useEffect } from 'react';
export default function App() {
const [pasted, setPasted] = useState('');
useEffect(() => {
const handlePaste = (event) => {
// 👇 Prevent default paste UI action
event.preventDefault();
setPasted(event.clipboardData.getData('text'));
}
window.addEventListener('paste', handlePaste)
return () => {
window.removeEventListener('paste', handlePaste)
};
})
return (
<div>
Pasted: <b>{pasted}</b>
<br />
<input placeholder="Message" type="text" id="message" />
<br />
<input placeholder="Sender" type="text" id="sender" />
</div>
);
}
Key takeaways
To listen for pastes on an element and get clipboard text, we can use the event.clipboardData.getData()
method. We can also handle pasted events on the entire window with window.addEventListener()
and prevent the default UI action using event.preventDefault()
.
To get clipboard data without pasting, we use the clipboard.readText()
method. These methods are useful for copying and pasting text between fields and preventing pasting behavior we don’t want.
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.