-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSuspenseDemo.tsx
106 lines (95 loc) · 2.7 KB
/
SuspenseDemo.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {
EvaluationContext,
InMemoryProvider,
OpenFeature,
OpenFeatureProvider,
useBooleanFlagValue
} from "@openfeature/react-sdk";
import { Suspense } from "react";
import { useSearchParams } from "react-router-dom";
import { SUSPENSE_DEMO_EXPLANATION, SUSPENSE_DEMO_NAME } from "../constants";
import hourglass from "../hourglass.svg";
import logo from "../logo.svg";
import "./Demo.css";
const PROVIDER_NAME = SUSPENSE_DEMO_NAME;
/**
* This component is associated with a provider that becomes ready after a few seconds.
* It demonstrates the "Suspense" support of the React SDK.
*/
function SuspenseDemo() {
const [searchParams] = useSearchParams();
OpenFeature.setProvider(
PROVIDER_NAME,
new DelayedInMemoryProvider(
{
"new-message": {
disabled: false,
variants: {
on: true,
off: false,
},
defaultVariant: "on",
},
},
Number.parseInt(searchParams.get("delay") || "3000")
)
);
return (
// This page is scoped to the "suspense" provider.
// Enable suspense for this context (can be overridden in hooks).
<OpenFeatureProvider domain={PROVIDER_NAME} suspend={true}>
<Content />
</OpenFeatureProvider>
);
}
function Content() {
return (
<div className="Demo">
<header className="Demo-header">
<p className="Demo-description small-text bounded-text">{SUSPENSE_DEMO_EXPLANATION}</p>
<Suspense fallback={<Fallback />}>
<Spinner />
</Suspense>
</header>
</div>
);
}
function Spinner() {
// evaluate flag with basic API
const showNewMessage = useBooleanFlagValue("new-message", false);
return (
<>
<img src={logo} className="Demo-logo Demo-spin" alt="logo" />
{showNewMessage ? (
<p>Welcome to this OpenFeature-enabled React app!</p>
) : (
<p>Welcome to this React app.</p>
)}
</>
);
}
function Fallback() {
return (
<>
<img src={hourglass} className="Demo-logo Fallback-img" alt="hourglass" />
<p>Waiting for provider to be ready...</p>
</>
);
}
/**
* A provider who's initialize is delayed for 'delay' seconds to demonstrate the React SDK's Suspense features.
*/
class DelayedInMemoryProvider extends InMemoryProvider {
constructor(
flagConfiguration: ConstructorParameters<typeof InMemoryProvider>[0],
private delay: number
) {
super(flagConfiguration);
}
// artificially delay our init (delaying PROVIDER_READY event)
async initialize(context?: EvaluationContext | undefined): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, this.delay));
return super.initialize(context);
}
}
export default SuspenseDemo;