1
- import { useEffect , useState } from "react" ;
1
+ import { useEffect , useState , useRef } from "react" ;
2
2
import { AppState , Platform } from "react-native" ;
3
3
import { clipboard } from "../utils/clipboard" ;
4
4
5
5
export const useClipboard = ( ) => {
6
6
const [ clipboardContent , setClipboardContent ] = useState < string > ( "" ) ;
7
7
const [ hasCopiedText , setHasCopiedText ] = useState ( false ) ;
8
8
const [ history , setHistory ] = useState < string [ ] > ( [ ] ) ;
9
- const [ previousContent , setPreviousContent ] = useState < string > ( "" ) ;
9
+ const previousContentRef = useRef < string > ( "" ) ;
10
+ const isMounted = useRef ( true ) ;
10
11
11
12
const checkClipboard = async ( ) => {
12
13
try {
13
14
const content = await clipboard . getString ( ) ;
14
- if ( content !== previousContent ) {
15
- setPreviousContent ( content ) ;
15
+ if ( content !== previousContentRef . current ) {
16
+ previousContentRef . current = content ;
16
17
setClipboardContent ( content ) ;
17
18
setHasCopiedText ( content . length > 0 ) ;
18
19
addToHistory ( content ) ;
@@ -24,66 +25,60 @@ export const useClipboard = () => {
24
25
25
26
const addToHistory = ( content : string ) => {
26
27
if ( content . trim ( ) && content !== history [ 0 ] ) {
27
- setHistory ( ( prev ) => [ content , ...prev . slice ( 0 , 49 ) ] ) ; // Keep last 50 items
28
+ setHistory ( ( prev ) => [ content , ...prev . slice ( 0 , 49 ) ] ) ;
28
29
}
29
30
} ;
30
31
31
- // useEffect(() => {
32
- // const initialLoad = async () => {
33
- // const content = await clipboard.getString();
34
- // setClipboardContent(content);
35
- // setHasCopiedText(content.length > 0);
36
- // addToHistory(content);
37
- // };
38
- // initialLoad();
39
-
40
- // const subscription = clipboard.addListener((content) => {
41
- // setClipboardContent(content);
42
- // setHasCopiedText(content.length > 0);
43
- // addToHistory(content);
44
- // });
45
-
46
- // return () => {
47
- // clipboard.removeListener(subscription);
48
- // };
49
- // }, []);
50
-
51
32
useEffect ( ( ) => {
52
- let intervalId : NodeJS . Timeout ;
53
- const subscription = AppState . addEventListener ( "change" , ( nextAppState ) => {
54
- if ( nextAppState === "active" ) {
33
+ isMounted . current = true ;
34
+
35
+ const handleAppStateChange = ( nextAppState : string ) => {
36
+ if ( nextAppState === "active" && isMounted . current ) {
55
37
checkClipboard ( ) ;
56
38
}
57
- } ) ;
39
+ } ;
40
+
41
+ const subscription = AppState . addEventListener (
42
+ "change" ,
43
+ handleAppStateChange
44
+ ) ;
58
45
59
46
// Initial check
60
47
checkClipboard ( ) ;
61
48
49
+ let intervalId : NodeJS . Timeout | null = null ;
50
+ let listener : any ;
62
51
if ( Platform . OS === "ios" ) {
63
- // Poll clipboard every 1.5 seconds for iOS
64
52
intervalId = setInterval ( checkClipboard , 1500 ) ;
65
53
} else {
66
- // Android listener
67
- const listenerSubscription = clipboard . addListener ( ( content ) => {
68
- setClipboardContent ( content ) ;
69
- setHasCopiedText ( content . length > 0 ) ;
70
- addToHistory ( content ) ;
54
+ listener = clipboard . addListener ( ( content : string ) => {
55
+ if ( isMounted . current ) {
56
+ previousContentRef . current = content ;
57
+ setClipboardContent ( content ) ;
58
+ setHasCopiedText ( content . length > 0 ) ;
59
+ addToHistory ( content ) ;
60
+ }
71
61
} ) ;
72
-
73
- return ( ) => {
74
- clipboard . removeListener ( listenerSubscription ) ;
75
- } ;
76
62
}
77
63
78
64
return ( ) => {
79
- clearInterval ( intervalId ) ;
65
+ isMounted . current = false ;
80
66
subscription . remove ( ) ;
67
+ if ( intervalId ) clearInterval ( intervalId ) ;
68
+ if ( Platform . OS === "android" ) {
69
+ clipboard . removeListener ( listener ) ;
70
+ }
81
71
} ;
82
- } , [ previousContent ] ) ;
72
+ } , [ ] ) ;
83
73
84
74
const copyToClipboard = async ( text : string ) => {
85
75
await clipboard . copy ( text ) ;
86
- addToHistory ( text ) ;
76
+ if ( isMounted . current ) {
77
+ previousContentRef . current = text ;
78
+ setClipboardContent ( text ) ;
79
+ setHasCopiedText ( true ) ;
80
+ addToHistory ( text ) ;
81
+ }
87
82
} ;
88
83
89
84
const getLatestClipboard = async ( ) => {
@@ -92,8 +87,11 @@ export const useClipboard = () => {
92
87
93
88
const clearClipboard = async ( ) => {
94
89
await clipboard . clear ( ) ;
95
- setClipboardContent ( "" ) ;
96
- setHasCopiedText ( false ) ;
90
+ if ( isMounted . current ) {
91
+ previousContentRef . current = "" ;
92
+ setClipboardContent ( "" ) ;
93
+ setHasCopiedText ( false ) ;
94
+ }
97
95
} ;
98
96
99
97
return {
0 commit comments