I am trying to build a component with some validations depending on user’s clipboard.
import { useState } from 'react'
export default function useCopiedFromClipboard() {
const [copiedData, setCopiedData] = useState<string>('')
navigator.clipboard
.readText()
.then((text) => {
setCopiedData(text)
})
.catch((err) => {
console.error('Failed to read clipboard contents: ', err)
})
return { copiedData }
}
So what I really want to do is use this hook inside a component.
import React from 'react'
export default function MyComponent() {
const {copiedData} = useCopiedFromClipboard()
useEffect(()=>{
console.log('Run')
},[copiedData])
return (
<></>
)
}
I am expecting this useEffect to run everytime the user copies something to their clipboard. But this is not working.
Does anyone have any idea of how to implement this one ?
3
Answers
The reason is that your
useCopiedFromClipboard
hook only reads the clipboard content once, when the component mounts, and does not update it when the clipboard changes. Therefore, youruseEffect
hook does not run again when thecopiedData
state changes.To fix this, you need to use an event listener to monitor the clipboard changes, and update the
copiedData
state accordingly. You can use the Clipboard API to do this, which provides a copy event that fires when the user copies something to their clipboard.For example:
You can see the whole example here.
Hope this helps you
The problem with your code is that you’re only getting the value of the clipboard once, when you initialize the
useCopiedFromClipboard
hook for the first time. It does not ‘listen’ for more clipboard events.We can solve this by using a
useEffect
where we setup a listener on thecopy
event. When the event first we manually get the selected text in the document and set that value to the users clipboard. Then we can update the state with the same value.You can add some try catch as you wish, this should cover the bare logic.