1- import { useEffect , useMemo , useState } from 'react' ;
2- import { Dimensions } from 'react-native' ;
1+ import { useCallback , useEffect , useState } from 'react' ;
2+ import { Dimensions , ScaledSize } from 'react-native' ;
33
44/**
55 * A custom hook that provides functions to calculate dimensions based on
@@ -9,35 +9,46 @@ import { Dimensions } from 'react-native';
99 * @returns {Object } An object containing functions vh and vw.
1010 */
1111export const useScreenDimensions = ( rounded ?: boolean ) => {
12- const [ screenDimensions , setScreenDimensions ] = useState ( Dimensions . get ( 'screen' ) ) ;
12+ const [ screenDimensions , setScreenDimensions ] = useState ( ( ) => Dimensions . get ( 'screen' ) ) ;
1313
1414 useEffect ( ( ) => {
15- const subscriptions = Dimensions . addEventListener ( 'change' , ( { screen } ) => {
15+ const handleChange = ( { screen } : { screen : ScaledSize } ) => {
1616 setScreenDimensions ( ( prev ) => {
1717 const { height, width } = screen ;
1818 if ( prev . height !== height || prev . width !== width ) {
1919 return screen ;
2020 }
2121 return prev ;
2222 } ) ;
23- } ) ;
23+ } ;
24+ const subscription = Dimensions . addEventListener ( 'change' , handleChange ) ;
2425
25- return ( ) => subscriptions ?. remove ( ) ;
26- } , [ ] ) ;
26+ // We might have missed an update between calling `get` in render and
27+ // `addEventListener` in this handler, so we set it here. If there was
28+ // no change, React will filter out this update as a no-op.
29+ // pattern ref: react-native-repo/packages/react-native/Libraries/Utilities/useWindowDimensions.js
30+ handleChange ( { screen : Dimensions . get ( 'screen' ) } ) ;
2731
28- // eslint-disable-next-line react-hooks/exhaustive-deps
29- const vw = ( percentageWidth : number ) => {
30- const value = screenDimensions . width * ( percentageWidth / 100 ) ;
31- return rounded ? Math . round ( value ) : value ;
32- } ;
32+ return ( ) => {
33+ subscription . remove ( ) ;
34+ } ;
35+ } , [ ] ) ;
3336
34- // eslint-disable-next-line react-hooks/exhaustive-deps
35- const vh = ( percentageHeight : number ) => {
36- const value = screenDimensions . height * ( percentageHeight / 100 ) ;
37- return rounded ? Math . round ( value ) : value ;
38- } ;
37+ const vw = useCallback (
38+ ( percentageWidth : number ) => {
39+ const value = screenDimensions . width * ( percentageWidth / 100 ) ;
40+ return rounded ? Math . round ( value ) : value ;
41+ } ,
42+ [ rounded , screenDimensions . width ] ,
43+ ) ;
3944
40- const screenDimensionFunctions = useMemo ( ( ) => ( { vh, vw } ) , [ vh , vw ] ) ;
45+ const vh = useCallback (
46+ ( percentageHeight : number ) => {
47+ const value = screenDimensions . height * ( percentageHeight / 100 ) ;
48+ return rounded ? Math . round ( value ) : value ;
49+ } ,
50+ [ rounded , screenDimensions . height ] ,
51+ ) ;
4152
42- return screenDimensionFunctions ;
53+ return { vh , vw } ;
4354} ;
0 commit comments