@@ -15,7 +15,13 @@ import {
15
15
Component ,
16
16
} from "preact" ;
17
17
import type { ComponentChildren , FunctionComponent , VNode } from "preact" ;
18
- import { useContext , useEffect , useRef , useState } from "preact/hooks" ;
18
+ import {
19
+ useContext ,
20
+ useEffect ,
21
+ useRef ,
22
+ useState ,
23
+ useCallback ,
24
+ } from "preact/hooks" ;
19
25
import { setupRerender , act } from "preact/test-utils" ;
20
26
21
27
const sleep = ( ms ?: number ) => new Promise ( r => setTimeout ( r , ms ) ) ;
@@ -1001,4 +1007,57 @@ describe("@preact/signals", () => {
1001
1007
expect ( spy ) . to . have . been . calledWith ( "willmount:1" ) ;
1002
1008
} ) ;
1003
1009
} ) ;
1010
+
1011
+ describe ( "useComputed" , ( ) => {
1012
+ it ( "should recompute and update dependency list when the compute function changes" , async ( ) => {
1013
+ const s1 = signal ( 1 ) ;
1014
+ const s2 = signal ( "a" ) ;
1015
+
1016
+ function App ( { x } : { x : Signal } ) {
1017
+ const fn = useCallback ( ( ) => {
1018
+ return x . value ;
1019
+ } , [ x ] ) ;
1020
+
1021
+ const c = useComputed ( fn ) ;
1022
+ return < span > { c . value } </ span > ;
1023
+ }
1024
+
1025
+ render ( < App x = { s1 } /> , scratch ) ;
1026
+ expect ( scratch . textContent ) . to . equal ( "1" ) ;
1027
+
1028
+ render ( < App x = { s2 } /> , scratch ) ;
1029
+ expect ( scratch . textContent ) . to . equal ( "a" ) ;
1030
+
1031
+ s1 . value = 2 ;
1032
+ rerender ( ) ;
1033
+ expect ( scratch . textContent ) . to . equal ( "a" ) ;
1034
+
1035
+ s2 . value = "b" ;
1036
+ rerender ( ) ;
1037
+ expect ( scratch . textContent ) . to . equal ( "b" ) ;
1038
+ } ) ;
1039
+
1040
+ it ( "should not recompute when the compute function doesn't change and dependency values don't change" , async ( ) => {
1041
+ const s1 = signal ( 1 ) ;
1042
+ const spy = sinon . spy ( ) ;
1043
+
1044
+ function App ( { x } : { x : Signal } ) {
1045
+ const fn = useCallback ( ( ) => {
1046
+ spy ( ) ;
1047
+ return x . value ;
1048
+ } , [ x ] ) ;
1049
+
1050
+ const c = useComputed ( fn ) ;
1051
+ return < span > { c . value } </ span > ;
1052
+ }
1053
+
1054
+ render ( < App x = { s1 } /> , scratch ) ;
1055
+ expect ( scratch . textContent ) . to . equal ( "1" ) ;
1056
+ expect ( spy ) . to . have . been . calledOnce ;
1057
+
1058
+ rerender ( ) ;
1059
+ expect ( scratch . textContent ) . to . equal ( "1" ) ;
1060
+ expect ( spy ) . to . have . been . calledOnce ;
1061
+ } ) ;
1062
+ } ) ;
1004
1063
} ) ;
0 commit comments