1+ import { useEffect , useRef , useState } from 'react' ;
2+
3+ import type ReactNativeLDClient from '../../ReactNativeLDClient' ;
14import useLDClient from '../useLDClient' ;
25import { LDEvaluationDetailTyped } from './LDEvaluationDetail' ;
36
7+ function getTypedVariation < T extends boolean | number | string | unknown > (
8+ ldClient : ReactNativeLDClient ,
9+ key : string ,
10+ defaultValue : T ,
11+ ) : T {
12+ switch ( typeof defaultValue ) {
13+ case 'boolean' :
14+ return ldClient . boolVariation ( key , defaultValue as boolean ) as T ;
15+ case 'number' :
16+ return ldClient . numberVariation ( key , defaultValue as number ) as T ;
17+ case 'string' :
18+ return ldClient . stringVariation ( key , defaultValue as string ) as T ;
19+ case 'undefined' :
20+ case 'object' :
21+ return ldClient . jsonVariation ( key , defaultValue ) as T ;
22+ default :
23+ return ldClient . variation ( key , defaultValue ) ;
24+ }
25+ }
26+
427/**
528 * Determines the strongly typed variation of a feature flag.
629 *
@@ -15,21 +38,72 @@ export const useTypedVariation = <T extends boolean | number | string | unknown>
1538 defaultValue : T ,
1639) : T => {
1740 const ldClient = useLDClient ( ) ;
41+ const [ value , setValue ] = useState < T > ( ( ) =>
42+ ldClient ? getTypedVariation ( ldClient , key , defaultValue ) : defaultValue ,
43+ ) ;
44+ const valueRef = useRef < T > ( value ) ;
45+
46+ useEffect ( ( ) => {
47+ valueRef . current = value ;
48+ } , [ value ] ) ;
49+
50+ useEffect ( ( ) => {
51+ setValue ( getTypedVariation ( ldClient , key , defaultValue ) ) ;
52+ const handleChange = ( ) : void => {
53+ const newValue = getTypedVariation ( ldClient , key , defaultValue ) ;
54+ if ( newValue !== valueRef . current ) {
55+ setValue ( newValue ) ;
56+ }
57+ } ;
58+ ldClient . on ( 'change' , handleChange ) ;
59+ return ( ) => {
60+ ldClient . off ( 'change' , handleChange ) ;
61+ } ;
62+ } , [ key ] ) ;
1863
64+ return value ;
65+ } ;
66+
67+ function getTypedVariationDetail < T extends boolean | number | string | unknown > (
68+ ldClient : ReactNativeLDClient ,
69+ key : string ,
70+ defaultValue : T ,
71+ ) : LDEvaluationDetailTyped < T > {
72+ let detail : LDEvaluationDetailTyped < T > ;
1973 switch ( typeof defaultValue ) {
20- case 'boolean' :
21- return ldClient . boolVariation ( key , defaultValue as boolean ) as T ;
22- case 'number' :
23- return ldClient . numberVariation ( key , defaultValue as number ) as T ;
24- case 'string' :
25- return ldClient . stringVariation ( key , defaultValue as string ) as T ;
74+ case 'boolean' : {
75+ detail = ldClient . boolVariationDetail (
76+ key ,
77+ defaultValue as boolean ,
78+ ) as LDEvaluationDetailTyped < T > ;
79+ break ;
80+ }
81+ case 'number' : {
82+ detail = ldClient . numberVariationDetail (
83+ key ,
84+ defaultValue as number ,
85+ ) as LDEvaluationDetailTyped < T > ;
86+ break ;
87+ }
88+ case 'string' : {
89+ detail = ldClient . stringVariationDetail (
90+ key ,
91+ defaultValue as string ,
92+ ) as LDEvaluationDetailTyped < T > ;
93+ break ;
94+ }
2695 case 'undefined' :
27- case 'object' :
28- return ldClient . jsonVariation ( key , defaultValue ) as T ;
29- default :
30- return ldClient . variation ( key , defaultValue ) ;
96+ case 'object' : {
97+ detail = ldClient . jsonVariationDetail ( key , defaultValue ) as LDEvaluationDetailTyped < T > ;
98+ break ;
99+ }
100+ default : {
101+ detail = ldClient . variationDetail ( key , defaultValue ) as LDEvaluationDetailTyped < T > ;
102+ break ;
103+ }
31104 }
32- } ;
105+ return { ...detail , reason : detail . reason ?? null } ;
106+ }
33107
34108/**
35109 * Determines the strongly typed variation of a feature flag for a context, along with information about
@@ -55,48 +129,30 @@ export const useTypedVariationDetail = <T extends boolean | number | string | un
55129 defaultValue : T ,
56130) : LDEvaluationDetailTyped < T > => {
57131 const ldClient = useLDClient ( ) ;
132+ const [ detail , setDetail ] = useState < LDEvaluationDetailTyped < T > > ( ( ) =>
133+ ldClient
134+ ? getTypedVariationDetail ( ldClient , key , defaultValue )
135+ : { value : defaultValue , reason : null } ,
136+ ) ;
137+ const detailRef = useRef < LDEvaluationDetailTyped < T > > ( detail ) ;
58138
59- switch ( typeof defaultValue ) {
60- case 'boolean' : {
61- const detail = ldClient . boolVariationDetail ( key , defaultValue as boolean ) ;
62-
63- return {
64- ...detail ,
65- reason : detail . reason ?? null ,
66- } as LDEvaluationDetailTyped < T > ;
67- }
68- case 'number' : {
69- const detail = ldClient . numberVariationDetail ( key , defaultValue as number ) ;
139+ useEffect ( ( ) => {
140+ detailRef . current = detail ;
141+ } , [ detail ] ) ;
70142
71- return {
72- ...detail ,
73- reason : detail . reason ?? null ,
74- } as LDEvaluationDetailTyped < T > ;
75- }
76- case 'string' : {
77- const detail = ldClient . stringVariationDetail ( key , defaultValue as string ) ;
143+ useEffect ( ( ) => {
144+ setDetail ( getTypedVariationDetail ( ldClient , key , defaultValue ) ) ;
145+ const handleChange = ( ) => {
146+ const newDetail = getTypedVariationDetail ( ldClient , key , defaultValue ) ;
147+ if ( newDetail . value !== detailRef . current . value ) {
148+ setDetail ( newDetail ) ;
149+ }
150+ } ;
151+ ldClient . on ( 'change' , handleChange ) ;
152+ return ( ) => {
153+ ldClient . off ( 'change' , handleChange ) ;
154+ } ;
155+ } , [ key ] ) ;
78156
79- return {
80- ...detail ,
81- reason : detail . reason ?? null ,
82- } as LDEvaluationDetailTyped < T > ;
83- }
84- case 'undefined' :
85- case 'object' : {
86- const detail = ldClient . jsonVariationDetail ( key , defaultValue ) ;
87-
88- return {
89- ...detail ,
90- reason : detail . reason ?? null ,
91- } as LDEvaluationDetailTyped < T > ;
92- }
93- default : {
94- const detail = ldClient . variationDetail ( key , defaultValue ) ;
95-
96- return {
97- ...detail ,
98- reason : detail . reason ?? null ,
99- } as LDEvaluationDetailTyped < T > ;
100- }
101- }
157+ return detail ;
102158} ;
0 commit comments