0
# State-based Control
1
2
The state-based approach uses the controlled component pattern, where you manage the progress state in your component and pass it to the LoadingBar as a prop. This provides React-style declarative control over the loading bar.
3
4
## Basic Setup
5
6
Control the loading bar by managing progress state:
7
8
```typescript
9
import React, { useState } from "react";
10
import LoadingBar from "react-top-loading-bar";
11
12
const App = () => {
13
const [progress, setProgress] = useState(0);
14
15
return (
16
<div>
17
<LoadingBar
18
color="#f11946"
19
progress={progress}
20
onLoaderFinished={() => setProgress(0)}
21
/>
22
<button onClick={() => setProgress(100)}>Complete</button>
23
</div>
24
);
25
};
26
```
27
28
## LoadingBar Props for State Control
29
30
```typescript { .api }
31
interface IProps {
32
// State Control
33
progress?: number;
34
onLoaderFinished?: () => void;
35
36
// Visual Properties
37
color?: string;
38
background?: string;
39
height?: number;
40
shadow?: boolean;
41
className?: string;
42
containerClassName?: string;
43
style?: CSSProperties;
44
containerStyle?: CSSProperties;
45
shadowStyle?: CSSProperties;
46
47
// Animation Timing
48
loaderSpeed?: number;
49
transitionTime?: number;
50
waitingTime?: number;
51
}
52
```
53
54
## Key Props
55
56
```typescript { .api }
57
/**
58
* Current progress value (0-100)
59
*/
60
progress?: number;
61
62
/**
63
* Callback fired when loading animation completes
64
* Called after the bar reaches 100% and fade animation finishes
65
*/
66
onLoaderFinished?: () => void;
67
```
68
69
## Usage Examples
70
71
### Simple Progress Control
72
73
```typescript
74
const SimpleProgress = () => {
75
const [progress, setProgress] = useState(0);
76
77
const handleStart = () => setProgress(20);
78
const handleIncrease = () => setProgress(prev => Math.min(prev + 20, 100));
79
const handleComplete = () => setProgress(100);
80
81
return (
82
<div>
83
<LoadingBar
84
color="blue"
85
progress={progress}
86
onLoaderFinished={() => setProgress(0)}
87
/>
88
<button onClick={handleStart}>Start (20%)</button>
89
<button onClick={handleIncrease}>+20%</button>
90
<button onClick={handleComplete}>Complete</button>
91
</div>
92
);
93
};
94
```
95
96
### API Loading State
97
98
```typescript
99
const ApiExample = () => {
100
const [progress, setProgress] = useState(0);
101
const [loading, setLoading] = useState(false);
102
103
const fetchData = async () => {
104
setLoading(true);
105
setProgress(10);
106
107
try {
108
// Start request
109
setProgress(30);
110
const response = await fetch("/api/data");
111
112
// Processing
113
setProgress(70);
114
const data = await response.json();
115
116
// Complete
117
setProgress(100);
118
} catch (error) {
119
setProgress(100); // Complete on error too
120
} finally {
121
setLoading(false);
122
}
123
};
124
125
return (
126
<div>
127
<LoadingBar
128
color="green"
129
progress={progress}
130
onLoaderFinished={() => setProgress(0)}
131
/>
132
<button onClick={fetchData} disabled={loading}>
133
{loading ? "Loading..." : "Fetch Data"}
134
</button>
135
</div>
136
);
137
};
138
```
139
140
### Form Submission Progress
141
142
```typescript
143
const FormSubmission = () => {
144
const [progress, setProgress] = useState(0);
145
const [formData, setFormData] = useState({ name: "", email: "" });
146
147
const handleSubmit = async (e: React.FormEvent) => {
148
e.preventDefault();
149
150
// Validation
151
setProgress(20);
152
await new Promise(resolve => setTimeout(resolve, 300));
153
154
// Submit
155
setProgress(50);
156
await fetch("/api/submit", {
157
method: "POST",
158
body: JSON.stringify(formData),
159
});
160
161
// Processing
162
setProgress(80);
163
await new Promise(resolve => setTimeout(resolve, 500));
164
165
// Complete
166
setProgress(100);
167
};
168
169
return (
170
<div>
171
<LoadingBar
172
color="purple"
173
progress={progress}
174
onLoaderFinished={() => {
175
setProgress(0);
176
alert("Form submitted successfully!");
177
}}
178
/>
179
<form onSubmit={handleSubmit}>
180
<input
181
value={formData.name}
182
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
183
placeholder="Name"
184
/>
185
<input
186
value={formData.email}
187
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
188
placeholder="Email"
189
/>
190
<button type="submit">Submit</button>
191
</form>
192
</div>
193
);
194
};
195
```
196
197
### Multi-step Process
198
199
```typescript
200
const MultiStepProcess = () => {
201
const [progress, setProgress] = useState(0);
202
const [currentStep, setCurrentStep] = useState(0);
203
204
const steps = [
205
{ name: "Initialize", progress: 10 },
206
{ name: "Validate", progress: 30 },
207
{ name: "Process", progress: 60 },
208
{ name: "Finalize", progress: 90 },
209
{ name: "Complete", progress: 100 },
210
];
211
212
const executeStep = async (stepIndex: number) => {
213
setCurrentStep(stepIndex);
214
setProgress(steps[stepIndex].progress);
215
216
// Simulate step execution
217
await new Promise(resolve => setTimeout(resolve, 1000));
218
219
if (stepIndex < steps.length - 1) {
220
executeStep(stepIndex + 1);
221
}
222
};
223
224
return (
225
<div>
226
<LoadingBar
227
color="orange"
228
progress={progress}
229
onLoaderFinished={() => {
230
setProgress(0);
231
setCurrentStep(0);
232
}}
233
/>
234
<p>Current Step: {steps[currentStep]?.name}</p>
235
<button onClick={() => executeStep(0)}>Start Process</button>
236
</div>
237
);
238
};
239
```
240
241
### File Upload with Progress
242
243
```typescript
244
const FileUpload = () => {
245
const [progress, setProgress] = useState(0);
246
247
const uploadFile = (file: File) => {
248
const formData = new FormData();
249
formData.append("file", file);
250
251
const xhr = new XMLHttpRequest();
252
253
// Track upload progress
254
xhr.upload.addEventListener("progress", (e) => {
255
if (e.lengthComputable) {
256
const percentComplete = (e.loaded / e.total) * 100;
257
setProgress(percentComplete);
258
}
259
});
260
261
xhr.onload = () => {
262
setProgress(100);
263
};
264
265
xhr.open("POST", "/upload");
266
xhr.send(formData);
267
};
268
269
return (
270
<div>
271
<LoadingBar
272
color="red"
273
progress={progress}
274
onLoaderFinished={() => setProgress(0)}
275
/>
276
<input
277
type="file"
278
onChange={(e) => e.target.files?.[0] && uploadFile(e.target.files[0])}
279
/>
280
</div>
281
);
282
};
283
```
284
285
## Visual Customization
286
287
Customize appearance through props:
288
289
```typescript
290
<LoadingBar
291
progress={progress}
292
color="#ff6b6b"
293
height={4}
294
shadow={true}
295
background="rgba(255,255,255,0.1)"
296
loaderSpeed={300}
297
transitionTime={200}
298
waitingTime={500}
299
className="custom-loader"
300
containerClassName="custom-container"
301
style={{ borderRadius: "2px" }}
302
onLoaderFinished={() => console.log("Done!")}
303
/>
304
```
305
306
## Important Notes
307
308
- **Progress Range**: Progress values should be between 0 and 100
309
- **Auto Reset**: Use `onLoaderFinished` callback to reset progress to 0 after completion
310
- **Smooth Transitions**: The loading bar automatically animates between progress values
311
- **Complete State**: Setting progress to 100 triggers the completion animation
312
- **No Conflicts**: Do not use progress prop with ref methods simultaneously