use Copy (React)
Copy text to your clipboard, and know when it's done so you can change the
button's text to copied!
.
typescriptjavascript
import { useState, useCallback, useRef } from 'react'
export type UseCopyProps = {
copiedTimeout?: number
}
type CopyFn = (text: string) => Promise<void>
export const useCopy = ({ copiedTimeout = 2000 }: UseCopyProps = {}): [
copy: CopyFn,
copied: boolean
] => {
const [copied, setCopied] = useState(false)
const timeoutRef = useRef<ReturnType<typeof setTimeout>>()
const copy: CopyFn = useCallback(
async text => {
await navigator.clipboard.writeText(text)
setCopied(true)
if (timeoutRef.current) clearTimeout(timeoutRef.current)
timeoutRef.current = setTimeout(() => setCopied(false), copiedTimeout)
},
[copiedTimeout]
)
return [copy, copied]
}
import { useState, useCallback, useRef } from 'react'
export const useCopy = ({ copiedTimeout = 2000 } = {}) => {
const [copied, setCopied] = useState(false)
const timeoutRef = useRef()
const copy = useCallback(
async text => {
await navigator.clipboard.writeText(text)
setCopied(true)
if (timeoutRef.current) clearTimeout(timeoutRef.current)
timeoutRef.current = setTimeout(() => setCopied(false), copiedTimeout)
},
[copiedTimeout]
)
return [copy, copied]
}
Info
- We use
useCallback
, so that if you follow hook rules and use thecopy
function inside auseEffect
or anotheruseCallback
, you won't have code (re-)running unnecessarily.
useCopy implemented with useTemporaryState
typescriptjavascript
export type UseCopyProps = {
copiedTimeout?: number
}
type CopyFn = (text: string) => Promise<void>
export const useCopy = ({ copiedTimeout = 2000 }: UseCopyProps = {}): [
copy: CopyFn,
copied: boolean
] => {
const [copied, setCopied] = useTemporaryState(false, copiedTimeout)
const copy: CopyFn = useCallback(
async text => {
await navigator.clipboard.writeText(text)
setCopied(true)
},
[setCopied]
)
return [copy, copied]
}
export const useCopy = ({ copiedTimeout = 2000 } = {}) => {
const [copied, setCopied] = useTemporaryState(false, copiedTimeout)
const copy = useCallback(
async text => {
await navigator.clipboard.writeText(text)
setCopied(true)
},
[setCopied]
)
return [copy, copied]
}
Check out the SolidJS version here.