@@ -49,16 +49,15 @@ function App() {
4949}
5050
5151function MyComponent() {
52- const { isEnabled, getValue } = useFlags();
52+ const { isEnabled } = useFlags();
5353
54- const showNewFeature = isEnabled('new-dashboard');
55- const showBetaFeatures = isEnabled('beta-features');
56- const darkModeEnabled = getValue('dark-mode-default', false);
54+ const newDashboardFlag = isEnabled('new-dashboard');
55+ const betaFeaturesFlag = isEnabled('beta-features');
5756
5857 return (
59- <div className={darkModeEnabled ? 'dark' : ''} >
60- {showNewFeature !== undefined && showNewFeature && <NewDashboard />}
61- {showBetaFeatures !== undefined && showBetaFeatures && <BetaFeatures />}
58+ <div>
59+ {newDashboardFlag.isReady && newDashboardFlag.enabled && <NewDashboard />}
60+ {betaFeaturesFlag.isReady && betaFeaturesFlag.enabled && <BetaFeatures />}
6261 <button>Click me</button>
6362 </div>
6463 );
@@ -90,11 +89,11 @@ function App() {
9089function MyComponent() {
9190 const { isEnabled } = useFlags();
9291
93- const showNewFeature = isEnabled('new-feature');
92+ const newFeatureFlag = isEnabled('new-feature');
9493
9594 return (
9695 <div>
97- {showNewFeature !== undefined && showNewFeature && <NewFeature />}
96+ {newFeatureFlag.isReady && newFeatureFlag.enabled && <NewFeature />}
9897 <button>Click me</button>
9998 </div>
10099 );
@@ -162,25 +161,55 @@ const showNewUI = isEnabled('new-ui-rollout');`}
162161<CodeBlock language = " tsx" >
163162{ ` const {
164163 isEnabled,
165- getValue,
166164 fetchAllFlags,
167165 updateUser,
168166 refresh
169167} = useFlags();
170168
171- // Check if flag is enabled (returns boolean | undefined)
172- const showFeature = isEnabled('my-feature'); // undefined if not evaluated yet
173- const darkModeDefault = getValue('dark-mode', false);
169+ // Get flag state with loading information
170+ const featureFlag = isEnabled('my-feature');
171+ // Returns: { enabled: boolean, isLoading: boolean, isReady: boolean }
172+
173+ // Conditional rendering - clean and predictable
174+ {featureFlag.isReady && featureFlag.enabled && <NewFeature />}
174175
175- // Only render when flag is evaluated
176- {showFeature !== undefined && (
177- showFeature ? <NewFeature /> : <OldFeature />
178- )}
176+ // Show loading states explicitly
177+ {featureFlag.isLoading && <LoadingSpinner />}
178+ {!featureFlag.isReady && <Skeleton />}
179179
180180// Refresh all flags
181181await fetchAllFlags(); ` }
182182</CodeBlock >
183183
184+ ## Flag States
185+
186+ The ` isEnabled ` function returns a flag state object with loading information:
187+
188+ <CodeBlock language = " tsx" >
189+ { ` const { isEnabled } = useFlags();
190+ const myFlag = isEnabled('my-feature');
191+
192+ // Always returns an object with these properties:
193+ myFlag.enabled // boolean - the flag value
194+ myFlag.isReady // boolean - true when flag has been evaluated
195+ myFlag.isLoading // boolean - true while fetching from server
196+
197+ // Clean, predictable conditional rendering
198+ {myFlag.isReady && myFlag.enabled && <MyFeature />}
199+
200+ // Show loading states when needed
201+ {myFlag.isLoading && <LoadingSpinner />}
202+ {!myFlag.isReady && <Skeleton />}
203+ {myFlag.isReady && myFlag.enabled && <Feature />} ` }
204+ </CodeBlock >
205+
206+ ** Benefits:**
207+ - No ` undefined ` checks required
208+ - Explicit loading states
209+ - More predictable behavior
210+ - Better TypeScript support
211+ - Cleaner component code
212+
184213## Why isPending Matters
185214
186215The ` isPending ` prop is crucial for preventing race conditions and ensuring consistent user experiences:
@@ -246,29 +275,55 @@ Enable debug mode to see flag evaluation in the browser console.
246275
247276## Performance Benefits
248277
249- - ** Client-side Caching** : Flags are cached in IndexedDB and localStorage for instant loading
278+ - ** Client-side Caching** : Flags are cached in localStorage for instant loading
250279- ** Intelligent Updates** : Only re-evaluates flags when user context changes
251280- ** Background Sync** : Fetches flag updates without blocking the UI
252281- ** Minimal Bundle Size** : Lightweight SDK with zero external dependencies
253282
254283## Best Practices
255284
256- 1 . ** Use ` isPending ` ** with authentication to prevent race conditions
257- 2 . ** Pass Custom Properties** for granular targeting and A/B testing
258- 3 . ** Enable Debug Mode** during development to monitor flag evaluation
259- 4 . ** Handle Flag Evaluation States** properly - flags return ` undefined ` until evaluated
260- 5 . ** Update User Context** after profile changes to refresh flag evaluation
285+ 1 . ** Use ` isEnabled ` for flag states** - returns loading and ready information
286+ 2 . ** Use ` isPending ` ** with authentication to prevent race conditions
287+ 3 . ** Pass Custom Properties** for granular targeting and A/B testing
288+ 4 . ** Enable Debug Mode** during development to monitor flag evaluation
289+ 5 . ** Check ` isReady ` ** before showing features to avoid flash of incorrect content
290+ 6 . ** Update User Context** after profile changes to refresh flag evaluation
261291
262292<CodeBlock language = " tsx" >
263- { ` // Best practice: Wait for flag evaluation before rendering
293+ { ` // ✅ Recommended: Check isReady before rendering features
264294function FeatureComponent() {
265295 const { isEnabled } = useFlags();
266- const showNewFeature = isEnabled('new-feature');
296+ const featureFlag = isEnabled('new-feature');
267297
268- // Don't render until flag is evaluated
269- if (showNewFeature === undefined) return <Skeleton />;
298+ // Always check isReady to avoid flash of wrong content
299+ if (!featureFlag.isReady) return <Skeleton />;
300+ return featureFlag.enabled ? <NewFeature /> : <OldFeature />;
301+ }
302+
303+ // ✅ Show loading states explicitly
304+ function FeatureWithLoading() {
305+ const { isEnabled } = useFlags();
306+ const featureFlag = isEnabled('new-feature');
270307
271- return showNewFeature ? <NewFeature /> : <OldFeature />;
308+ if (featureFlag.isLoading) return <LoadingSpinner />;
309+ if (!featureFlag.isReady) return <Skeleton />;
310+ return featureFlag.enabled ? <NewFeature /> : <OldFeature />;
311+ }
312+
313+ // ✅ Multiple flags in one component
314+ function Dashboard() {
315+ const { isEnabled } = useFlags();
316+ const darkMode = isEnabled('dark-mode');
317+ const newLayout = isEnabled('new-layout');
318+
319+ // Both flags must be ready before rendering
320+ if (!darkMode.isReady || !newLayout.isReady) return <Skeleton />;
321+
322+ return (
323+ <div className={darkMode.enabled ? 'dark' : ''}>
324+ {newLayout.enabled ? <NewLayout /> : <OldLayout />}
325+ </div>
326+ );
272327} ` }
273328</CodeBlock >
274329
0 commit comments