File tree Expand file tree Collapse file tree 4 files changed +44
-10
lines changed Expand file tree Collapse file tree 4 files changed +44
-10
lines changed Original file line number Diff line number Diff line change 1
- import { useRef } from 'react' ;
1
+ import { useMemo , useRef } from 'react' ;
2
2
/**
3
3
* @name useLatest
4
4
* @description - Hook that returns the stable reference of the value
5
5
* @category Utilities
6
6
*
7
7
* @template Value The type of the value
8
8
* @param {Value } value The value to get the previous value
9
- * @returns {Value } The previous value
9
+ * @returns {UseLatestReturn< Value> } The previous value
10
10
*
11
11
* @example
12
12
* const latestValue = useLatest(value);
13
13
*/
14
14
export const useLatest = ( value ) => {
15
15
const valueRef = useRef ( value ) ;
16
16
valueRef . current = value ;
17
- return valueRef . current ;
17
+ return useMemo (
18
+ ( ) => ( {
19
+ get value ( ) {
20
+ return valueRef . current ;
21
+ } ,
22
+ ref : valueRef
23
+ } ) ,
24
+ [ ]
25
+ ) ;
18
26
} ;
Original file line number Diff line number Diff line change 1
1
import { useCounter , useLatest } from '@siberiacancode/reactuse' ;
2
+ import { useEffect } from 'react' ;
2
3
3
4
const Demo = ( ) => {
4
5
const counter = useCounter ( ) ;
5
6
const latestCount = useLatest ( counter . value ) ;
6
7
8
+ useEffect ( ( ) => {
9
+ console . log ( 'latestCount' , latestCount . value ) ;
10
+ setInterval ( ( ) => {
11
+ console . log ( 'latestCount' , latestCount . value ) ;
12
+ } , 1000 ) ;
13
+ } , [ ] ) ;
14
+
7
15
return (
8
16
< div >
9
17
< p >
10
- You clicked < code > { counter . value } </ code > times, latest count is < code > { latestCount } </ code >
18
+ You clicked < code > { counter . value } </ code > times, latest count is{ ' ' }
19
+ < code > { latestCount . value } </ code >
11
20
</ p >
12
21
13
22
< button className = 'button' type = 'button' onClick = { ( ) => counter . inc ( ) } >
Original file line number Diff line number Diff line change @@ -5,7 +5,8 @@ import { useLatest } from './useLatest';
5
5
it ( 'Should use latest' , ( ) => {
6
6
const { result } = renderHook ( ( ) => useLatest ( 'value' ) ) ;
7
7
8
- expect ( result . current ) . toBe ( 'value' ) ;
8
+ expect ( result . current . value ) . toBe ( 'value' ) ;
9
+ expect ( result . current . ref . current ) . toBe ( 'value' ) ;
9
10
} ) ;
10
11
11
12
it ( 'Should maintain reference stability' , ( ) => {
@@ -14,5 +15,6 @@ it('Should maintain reference stability', () => {
14
15
} ) ;
15
16
16
17
rerender ( 'newValue' ) ;
17
- expect ( result . current ) . toEqual ( 'newValue' ) ;
18
+ expect ( result . current . value ) . toEqual ( 'newValue' ) ;
19
+ expect ( result . current . ref . current ) . toEqual ( 'newValue' ) ;
18
20
} ) ;
Original file line number Diff line number Diff line change 1
- import { useRef } from 'react' ;
1
+ import type { RefObject } from 'react' ;
2
+
3
+ import { useMemo , useRef } from 'react' ;
4
+
5
+ export interface UseLatestReturn < Value > {
6
+ ref : RefObject < Value > ;
7
+ value : Value ;
8
+ }
2
9
3
10
/**
4
11
* @name useLatest
@@ -7,13 +14,21 @@ import { useRef } from 'react';
7
14
*
8
15
* @template Value The type of the value
9
16
* @param {Value } value The value to get the previous value
10
- * @returns {Value } The previous value
17
+ * @returns {UseLatestReturn< Value> } The previous value
11
18
*
12
19
* @example
13
20
* const latestValue = useLatest(value);
14
21
*/
15
- export const useLatest = < Value > ( value : Value ) => {
22
+ export const useLatest = < Value > ( value : Value ) : UseLatestReturn < Value > => {
16
23
const valueRef = useRef < Value > ( value ) ;
17
24
valueRef . current = value ;
18
- return valueRef . current ;
25
+ return useMemo (
26
+ ( ) => ( {
27
+ get value ( ) {
28
+ return valueRef . current ;
29
+ } ,
30
+ ref : valueRef
31
+ } ) ,
32
+ [ ]
33
+ ) ;
19
34
} ;
You can’t perform that action at this time.
0 commit comments