-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
124 lines (110 loc) · 3.84 KB
/
index.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import * as request from './lib/index';
let rootElement = document.getElementById('root');
if (rootElement != null) {
const root = ReactDOM.createRoot(rootElement);
root.render(<Demos />);
}
function Demos() {
return <>
<h1>request: event handler demo</h1>
<RequestDemo />
<hr />
<h1>useRequest: auto-fetch demo</h1>
<UseRequestDemoAuto />
<hr />
<h1>useRequest: lazy-fetch demo</h1>
<UseRequestDemolazy />
</>;
}
// requestDemo makes a request when a button is clicked, using the
// request function.
function RequestDemo() {
let [zen, setZen] = useState(request.requestInitialState());
let indicator = indicatorFn(zen);
if (indicator) {
return indicator;
}
return <>
<input type="button" onClick={() => {
request.request("GET", "https://api.github.com/zen", {
callback: setZen
});
}} value="Make request" /><br />
<pre>
<code>{prettyOutput(zen)}</code>
</pre>
</>;
}
// useRequestDemoAuto makes a request as soon as the component is mounted using
// the useRequest hook.
function UseRequestDemoAuto() {
let zen = useCustomRequest("GET", "https://api.github.com/zen");
if (zen.indicator) {
return zen.indicator;
}
return <pre>
<code>{prettyOutput(zen)}</code>
</pre>;
}
// useRequestDemoAuto makes a request as soon when a button is clicked, using
// the useRequest hook.
function UseRequestDemolazy() {
let zen = useCustomRequest("GET", "https://api.github.com/zen", { lazy: true });
if (zen.indicator) {
return zen.indicator;
}
return <>
<input type="button" onClick={zen.fetch} value="Make request" /><br />
<pre>
<code>{prettyOutput(zen)}</code>
</pre>
</>;
}
// Loading is a component to be displayed when a request is still in progress.
function Loading() {
return <div>Loading...</div>;
}
// Error is component to be displayed if a request fails, either with a non-2xx
// response code or with an unexpected failure.
function Error({ message }) {
return <div style={{ borderLeft: "3px solid red", paddingLeft: "8px" }}>
<strong>Error:</strong> <code>{message}</code>
</div>;
}
// indicatorFn returns the Loading component if the request is loading or
// pending, the error component if an error happened, or null if neither
// condition is true.
function indicatorFn({status, loading, error}, pendingIsLoading?: boolean) {
if (loading || (pendingIsLoading && status === request.REQUEST_PENDING)) {
return <Loading />;
}
if (error) {
return <Error message={JSON.stringify(error)} />;
}
return null;
};
// useCustomrequest wraps useRequest with certain adaptations. In this case,
// it will set an indicator for easier rendering of loading and error states.
// It could also set extra headers, or change the request body.
// This is the expected pattern when customizing `useRequest` so that it can
// have custom and uniform behavior for an entire application.
// The same kind of wrapper can be written for the regular request function.
function useCustomRequest(method: string, url: string, opts?: request.useRequestOpts): (request.useRequestReturn & {indicator: any}) {
let rsp = request.useRequest(method, url, opts);
return {...rsp, indicator: indicatorFn(rsp, !opts?.lazy)}
}
// stringifyuseRequest is a function that helps us show the value returned
// by useRequest.
function prettyOutput(v: request.useRequestReturn | any): string {
return JSON.stringify({
reqID: v.reqID,
status: v.status,
data: v.data,
error: v.error,
loading: v.loading,
fetch: v.fetch,
lastFetch: v.lastFetch,
}, null, 4);
}