@@ -210,18 +210,24 @@ export const useExperiment: UseExperiment = (experimentKey, options = {}, overri
210210
211211 const finalReadyTimeout = options . timeout !== undefined ? options . timeout : timeout ;
212212 useEffect ( ( ) => {
213- if ( ! isClientReady ) {
213+ // Subscribe to initialzation promise only
214+ // 1. When client is using Sdk Key, which means the initialization will be asynchronous
215+ // and we need to wait for the promise and update decision.
216+ // 2. When client is using datafile only but client is not ready yet which means user
217+ // was provided as a promise and we need to subscribe and wait for user to become available.
218+ if ( optimizely . getIsUsingSdkKey ( ) || ! isClientReady ) {
214219 subscribeToInitialization ( optimizely , finalReadyTimeout , initState => {
215220 setState ( {
216221 ...getCurrentDecision ( ) ,
217222 ...initState ,
218223 } ) ;
219224 } ) ;
220225 }
221- } , [ isClientReady , finalReadyTimeout , getCurrentDecision , optimizely ] ) ;
226+ } , [ ] ) ;
222227
223228 useEffect ( ( ) => {
224- if ( options . autoUpdate ) {
229+ // Subscribe to update after first datafile is fetched and readyPromise is resolved to avoid redundant rendering.
230+ if ( optimizely . getIsReadyPromiseFulfilled ( ) && options . autoUpdate ) {
225231 return setupAutoUpdateListeners ( optimizely , HookType . EXPERIMENT , experimentKey , hooksLogger , ( ) => {
226232 setState ( prevState => ( {
227233 ...prevState ,
@@ -230,7 +236,7 @@ export const useExperiment: UseExperiment = (experimentKey, options = {}, overri
230236 } ) ;
231237 }
232238 return ( ) : void => { } ;
233- } , [ isClientReady , options . autoUpdate , optimizely , experimentKey , getCurrentDecision ] ) ;
239+ } , [ optimizely . getIsReadyPromiseFulfilled ( ) , options . autoUpdate , optimizely , experimentKey , getCurrentDecision ] ) ;
234240
235241 useEffect (
236242 ( ) =>
@@ -297,18 +303,24 @@ export const useFeature: UseFeature = (featureKey, options = {}, overrides = {})
297303
298304 const finalReadyTimeout = options . timeout !== undefined ? options . timeout : timeout ;
299305 useEffect ( ( ) => {
300- if ( ! isClientReady ) {
306+ // Subscribe to initialzation promise only
307+ // 1. When client is using Sdk Key, which means the initialization will be asynchronous
308+ // and we need to wait for the promise and update decision.
309+ // 2. When client is using datafile only but client is not ready yet which means user
310+ // was provided as a promise and we need to subscribe and wait for user to become available.
311+ if ( optimizely . getIsUsingSdkKey ( ) || ! isClientReady ) {
301312 subscribeToInitialization ( optimizely , finalReadyTimeout , initState => {
302313 setState ( {
303314 ...getCurrentDecision ( ) ,
304315 ...initState ,
305316 } ) ;
306317 } ) ;
307318 }
308- } , [ isClientReady , finalReadyTimeout , getCurrentDecision , optimizely ] ) ;
319+ } , [ ] ) ;
309320
310321 useEffect ( ( ) => {
311- if ( options . autoUpdate ) {
322+ // Subscribe to update after first datafile is fetched and readyPromise is resolved to avoid redundant rendering.
323+ if ( optimizely . getIsReadyPromiseFulfilled ( ) && options . autoUpdate ) {
312324 return setupAutoUpdateListeners ( optimizely , HookType . FEATURE , featureKey , hooksLogger , ( ) => {
313325 setState ( prevState => ( {
314326 ...prevState ,
@@ -317,7 +329,7 @@ export const useFeature: UseFeature = (featureKey, options = {}, overrides = {})
317329 } ) ;
318330 }
319331 return ( ) : void => { } ;
320- } , [ isClientReady , options . autoUpdate , optimizely , featureKey , getCurrentDecision ] ) ;
332+ } , [ optimizely . getIsReadyPromiseFulfilled ( ) , options . autoUpdate , optimizely , featureKey , getCurrentDecision ] ) ;
321333
322334 return [ state . isEnabled , state . variables , state . clientReady , state . didTimeout ] ;
323335} ;
@@ -373,18 +385,24 @@ export const useDecision: UseDecision = (flagKey, options = {}, overrides = {})
373385
374386 const finalReadyTimeout = options . timeout !== undefined ? options . timeout : timeout ;
375387 useEffect ( ( ) => {
376- if ( ! isClientReady ) {
388+ // Subscribe to initialzation promise only
389+ // 1. When client is using Sdk Key, which means the initialization will be asynchronous
390+ // and we need to wait for the promise and update decision.
391+ // 2. When client is using datafile only but client is not ready yet which means user
392+ // was provided as a promise and we need to subscribe and wait for user to become available.
393+ if ( optimizely . getIsUsingSdkKey ( ) || ! isClientReady ) {
377394 subscribeToInitialization ( optimizely , finalReadyTimeout , initState => {
378395 setState ( {
379396 ...getCurrentDecision ( ) ,
380397 ...initState ,
381398 } ) ;
382399 } ) ;
383400 }
384- } , [ isClientReady , finalReadyTimeout , getCurrentDecision , optimizely ] ) ;
401+ } , [ ] ) ;
385402
386403 useEffect ( ( ) => {
387- if ( options . autoUpdate ) {
404+ // Subscribe to update after first datafile is fetched and readyPromise is resolved to avoid redundant rendering.
405+ if ( optimizely . getIsReadyPromiseFulfilled ( ) && options . autoUpdate ) {
388406 return setupAutoUpdateListeners ( optimizely , HookType . FEATURE , flagKey , hooksLogger , ( ) => {
389407 setState ( prevState => ( {
390408 ...prevState ,
@@ -393,7 +411,7 @@ export const useDecision: UseDecision = (flagKey, options = {}, overrides = {})
393411 } ) ;
394412 }
395413 return ( ) : void => { } ;
396- } , [ isClientReady , options . autoUpdate , optimizely , flagKey , getCurrentDecision ] ) ;
414+ } , [ optimizely . getIsReadyPromiseFulfilled ( ) , options . autoUpdate , optimizely , flagKey , getCurrentDecision ] ) ;
397415
398416 return [ state . decision , state . clientReady , state . didTimeout ] ;
399417} ;
0 commit comments