├── .DS_Store
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anisul-Islam/react-typescript-documentation/61083ecc07cda5046e0e8b8b32736e908487ad2a/.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React + Typescript documentation
2 |
3 | - prerequisities - TypeScript, React Fundamentals
4 |
5 | ## 1. Introduction to TypeScript
6 |
7 | - What is TypeScript?
8 |
9 | - programming language developed by microsoft
10 | - superset of JavaScript
11 |
12 | - Why TypeScript?
13 |
14 | - adds static typing to JavaScript
15 | - it helps to see bugs when writing codes; easy to find and fix bugs
16 | - gives auto suggestion
17 | - provides better documentation
18 |
19 | - Course outcomes
20 | - props types
21 | - built-in data type props
22 | - user defined data type props
23 | - events props
24 | - hooks types
25 |
26 | ## 2. Environment setup
27 |
28 | - install node & VSCode
29 | - install react+ts -> `npx create-react-app appName --template typescript`
30 |
31 | ## 3. typescript for Props - built in types
32 |
33 | - built in types example -> string, number, boolean
34 | - extension .ts and component extension is .tsx not .js or .jsx
35 |
36 | ```tsx
37 | // auto completion -> props.
38 | // if we pass anything other than string as name props we will get error
39 | // component props is an object
40 | // User.tsx (version-1)
41 | import React from "react";
42 | const User = (props: {
43 | name: string;
44 | email: string;
45 | age: number;
46 | isRegistered: boolean;
47 | }) => {
48 | return (
49 |
50 |
{props.name}
51 |
{props.email}
52 |
{props.age} years old
53 | {props.isRegistered ? (
54 |
Registered Student
55 | ) : (
56 |
Unregistered Student
57 | )}
58 |
59 | );
60 | };
61 |
62 | export default User;
63 |
64 | // User.tsx (version-2)
65 | import React from "react";
66 |
67 | type UserProps = {
68 | name: string;
69 | email: string;
70 | age: number;
71 | isRegistered: boolean;
72 | };
73 | const User = (props: UserProps) => {
74 | return (
75 |
76 |
{props.name}
77 |
{props.email}
78 |
{props.age} years old
79 | {props.isRegistered ? (
80 |
Registered Student
81 | ) : (
82 |
Unregistered Student
83 | )}
84 |
85 | );
86 | };
87 | export default User;
88 |
89 | // User.tsx (version-3)
90 | import React from "react";
91 | type UserProps = {
92 | name: string;
93 | email: string;
94 | age: number;
95 | isRegistered: boolean;
96 | };
97 | const User = ({ name, email, age, isRegistered }: UserProps) => {
98 | return (
99 |
100 |
{name}
101 |
{email}
102 |
{age} years old
103 | {isRegistered ?
Registered Student
:
Unregistered Student
}
104 |
105 | );
106 | };
107 | export default User;
108 |
109 | // App.tsx
110 | import React from "react";
111 | import "./App.css";
112 | import User from "./components/User";
113 |
114 | function App() {
115 | return (
116 |
117 |
User Management App
118 |
124 |
130 |
131 | );
132 | }
133 |
134 | export default App;
135 |
136 | // void
137 | const handleClick = (): void => {
138 | console.log("clicked");
139 | };
140 | ```
141 |
142 | ## 4. typescript for Props - User defined types
143 |
144 | - Object, Array, Union, enum, tuple, any, custom type
145 |
146 | - object props
147 |
148 | ```tsx
149 | import React from "react";
150 |
151 | type UserProps = {
152 | user: {
153 | name: string;
154 | email: string;
155 | age: number;
156 | isRegistered: boolean;
157 | };
158 | };
159 | const User = ({ user }: UserProps) => {
160 | return (
161 |
162 |
{user.name}
163 |
{user.email}
164 |
{user.age} years old
165 | {user.isRegistered ? (
166 |
Registered Student
167 | ) : (
168 |
Unregistered Student
169 | )}
170 |
171 | );
172 | };
173 |
174 | export default User;
175 |
176 | // App.tsx
177 | import React from "react";
178 | import "./App.css";
179 | import User from "./components/User";
180 |
181 | const user1 = {
182 | name: "anisul islam",
183 | email: "anisul2010s@yahoo.co.uk",
184 | age: 32,
185 | isRegistered: true,
186 | };
187 | const user2 = {
188 | name: "Rabeya Begum",
189 | email: "rabu2010s@yahoo.co.uk",
190 | age: 31,
191 | isRegistered: false,
192 | };
193 |
194 | function App() {
195 | return (
196 |
197 |
User Management App
198 |
199 |
200 |
201 | );
202 | }
203 |
204 | export default App;
205 |
206 | // more updates for App.tsx
207 | import React from "react";
208 | import "./App.css";
209 | import User from "./components/User";
210 |
211 | const users = [
212 | {
213 | id: 1,
214 | name: "anisul islam",
215 | email: "anisul2010s@yahoo.co.uk",
216 | age: 32,
217 | isRegistered: true,
218 | },
219 | {
220 | id: 2,
221 | name: "Rabeya Begum",
222 | email: "rabu2010s@yahoo.co.uk",
223 | age: 31,
224 | isRegistered: false,
225 | },
226 | ];
227 |
228 | function App() {
229 | return (
230 |
231 |
User Management App
232 | {users.map((user) => (
233 |
234 | ))}
235 |
236 | );
237 | }
238 |
239 | export default App;
240 | ```
241 |
242 | - array props
243 |
244 | ```tsx
245 | // simple example
246 | import React from "react";
247 |
248 | type UserProps = {
249 | lang: string[];
250 | };
251 | const User = ({ lang }: UserProps) => {
252 | return (
253 |
254 |
255 | Speaks:{" "}
256 | {lang.map((language, index) => {
257 | return {language} ;
258 | })}
259 |
260 |
261 | );
262 | };
263 | export default User;
264 |
265 | // App.tsx
266 | import React from "react";
267 | import "./App.css";
268 | import User from "./components/User";
269 | function App() {
270 | return (
271 |
272 |
User Management App
273 |
274 |
275 | );
276 | }
277 | export default App;
278 |
279 | // complex example
280 | import React from "react";
281 |
282 | type UserProps = {
283 | user: {
284 | name: string;
285 | email: string;
286 | age: number;
287 | isRegistered: boolean;
288 | languages: string[];
289 | };
290 | };
291 | const User = ({ user }: UserProps) => {
292 | return (
293 |
294 |
{user.name}
295 |
{user.email}
296 |
{user.age} years old
297 | {user.isRegistered ? (
298 |
Registered Student
299 | ) : (
300 |
Unregistered Student
301 | )}
302 |
303 | Speaks:{" "}
304 | {user.languages.map((language, index) => {
305 | return {language} ;
306 | })}
307 |
308 |
309 | );
310 | };
311 | export default User;
312 |
313 | // App.tsx
314 | import React from "react";
315 | import "./App.css";
316 | import User from "./components/User";
317 |
318 | const users = [
319 | {
320 | id: 1,
321 | name: "anisul islam",
322 | email: "anisul2010s@yahoo.co.uk",
323 | age: 32,
324 | isRegistered: true,
325 | languages: ["Bangla", "English"],
326 | },
327 | {
328 | id: 2,
329 | name: "Rabeya Begum",
330 | email: "rabu2010s@yahoo.co.uk",
331 | age: 31,
332 | isRegistered: false,
333 | languages: ["Bangla", "English", "Finnish"],
334 | },
335 | ];
336 |
337 | function App() {
338 | return (
339 |
340 |
User Management App
341 | {users.map((user) => (
342 |
343 | ))}
344 |
345 | );
346 | }
347 | export default App;
348 |
349 | // one more array example
350 |
351 | // App.tsx
352 | import React from "react";
353 | import "./App.css";
354 | import User from "./components/User";
355 | const users = [
356 | {
357 | id: 1,
358 | name: "anisul islam",
359 | email: "anisul2010s@yahoo.co.uk",
360 | },
361 | {
362 | id: 2,
363 | name: "Rabeya Begum",
364 | email: "rabu2010s@yahoo.co.uk",
365 | },
366 | ];
367 |
368 | function App() {
369 | return (
370 |
371 |
User Management App
372 |
373 |
374 | );
375 | }
376 | export default App;
377 |
378 | // User.tsx
379 | import React from "react";
380 | type UserProps = {
381 | users: {
382 | id: number;
383 | name: string;
384 | email: string;
385 | }[];
386 | };
387 | const User = ({ users }: UserProps) => {
388 | return (
389 |
390 | {users.map((user) => {
391 | const { id, name, email } = user;
392 | return (
393 |
394 |
{name}
395 |
{email}
396 |
397 | );
398 | })}
399 |
400 | );
401 | };
402 | export default User;
403 | ```
404 |
405 | - union of types
406 |
407 | ```tsx
408 | // Message.tsx
409 | import React from "react";
410 |
411 | type MessageProps = {
412 | text: "ADD" | "UPDATE" | "DELETE";
413 | };
414 |
415 | const Message = (props: MessageProps) => {
416 | if (props.text === "ADD") {
417 | return User is added
;
418 | } else if (props.text === "UPDATE") {
419 | return User is updated
;
420 | }
421 | return User is deleted
;
422 | };
423 |
424 | export default Message;
425 |
426 | // App.tsx
427 | function App() {
428 | return (
429 |
430 |
User Management App
431 |
432 | {/* */}
433 |
434 | );
435 | }
436 |
437 | export default App;
438 | ```
439 |
440 | - children props
441 |
442 | ```tsx
443 | // Card.tsx
444 | import React from "react";
445 | type CardProps = {
446 | children: React.ReactNode;
447 | };
448 | const Card = (props: CardProps) => {
449 | return {props.children}
;
450 | };
451 |
452 | export default Card;
453 |
454 | //User.tsx
455 | import React from "react";
456 | import Card from "./Card";
457 |
458 | type UserProps = {
459 | user: {
460 | name: string;
461 | email: string;
462 | age: number;
463 | isRegistered: boolean;
464 | languages: string[];
465 | };
466 | };
467 | const User = ({ user }: UserProps) => {
468 | return (
469 |
470 | {user.name}
471 | {user.email}
472 | {user.age} years old
473 | {user.isRegistered ? (
474 | Registered Student
475 | ) : (
476 | Unregistered Student
477 | )}
478 |
479 | Speaks:{" "}
480 | {user.languages.map((language, index) => {
481 | return {language} ;
482 | })}
483 |
484 |
485 | );
486 | };
487 | export default User;
488 | ```
489 |
490 | ## 5. Typing Event Props
491 |
492 | - example
493 |
494 | ```tsx
495 | // Typing event props
496 | click event: event: React.MouseEvent
497 | type ButtonProps = {
498 | handleClick: (event: React.MouseEvent) => void;
499 | handleChange: (event: React.ChangeEvent) => void
500 | };
501 |
502 | //App.tsx
503 | import React, { useState } from "react";
504 |
505 | type NewUserProps = {
506 | name: string;
507 | email: string;
508 | };
509 | const NewUser = () => {
510 | const [user, setUser] = useState({ name: "", email: "" });
511 |
512 | const handleChange = (event: React.ChangeEvent) => {
513 | const fieldName = event.target.name;
514 | setUser({ ...user, [fieldName]: event.target.value });
515 | };
516 |
517 | const handleSubmit = (event: React.FormEvent) => {
518 | event.preventDefault();
519 | console.log(user);
520 | };
521 |
522 |
523 | const handleSubmit = (event: FormEvent) => {
524 | event.preventDefault();
525 | const newTodo = { id: Math.random().toString(), title };
526 | onAddNewTodo(newTodo);
527 |
528 | // const target = event.target as typeof event.target & {
529 | // title: { value: string };
530 | // };
531 | // console.log(target.title.value);
532 | };
533 | return (
534 |
535 |
Create User
536 |
565 |
566 | );
567 | };
568 |
569 | export default NewUser;
570 |
571 | ```
572 |
573 | ## 6. Style Props
574 |
575 | - example
576 |
577 | ```tsx
578 | // props for styles -> React.CSSProperties
579 | import React from "react";
580 |
581 | type ButtonProps = {
582 | styles: React.CSSProperties;
583 | };
584 |
585 | const Button = (props: ButtonProps) => {
586 | return ;
587 | };
588 |
589 | export default Button;
590 |
591 | import "./App.css";
592 | import Button from "./components/Button";
593 |
594 | function App() {
595 | return (
596 |
597 |
600 |
601 | );
602 | }
603 |
604 | export default App;
605 | ```
606 |
607 | ## 7. Typing useState Hooks
608 |
609 | - example
610 |
611 | ```tsx
612 | import React, { useState } from "react";
613 | import "./App.css";
614 |
615 | const App = () => {
616 | // type is automatically infereed as number
617 | const [count, setCount] = useState(0);
618 |
619 | const handleIncrement = (): void => {
620 | setCount((count) => count + 1);
621 | };
622 |
623 | const handleDecrement = (): void => {
624 | setCount((count) => count - 1);
625 | };
626 |
627 | return (
628 |
629 |
Count : {count}
630 |
631 |
632 |
633 | );
634 | };
635 |
636 | export default App;
637 |
638 | // dealing with future values in useState Hook
639 | import React, { useState } from "react";
640 | import "./App.css";
641 |
642 | type User = {
643 | id: number;
644 | name: string;
645 | };
646 |
647 | const App = () => {
648 | // const [data, setData] = useState(null);
649 | const [data, setData] = useState(null);
650 |
651 | const handleSetData = () => {
652 | // setData("Anisul islam");
653 | setData({ id: 101, name: "anisul islam" });
654 | console.log(data);
655 | };
656 |
657 | return (
658 |
659 |
UseState Future value
660 |
661 | {/* {data &&
{data}
} */}
662 |
663 |
664 |
665 | );
666 | };
667 |
668 | export default App;
669 |
670 | // type asertion - without optional chaining operator
671 | import React, { useState } from "react";
672 | import "./App.css";
673 |
674 | type User = {
675 | id: number;
676 | name: string;
677 | };
678 |
679 | const App = () => {
680 | // const [data, setData] = useState(null);
681 | const [data, setData] = useState({} as User);
682 |
683 | const handleSetData = () => {
684 | // setData("Anisul islam");
685 | setData({ id: 101, name: "anisul islam" });
686 | console.log(data);
687 | };
688 |
689 | return (
690 |
691 |
UseState Future value
692 |
693 | {/* {data &&
{data}
} */}
694 |
{data.id}
695 |
{data.name}
696 |
697 | );
698 | };
699 |
700 | export default App;
701 | ```
702 |
703 | ## 8. Typing useReducer Hooks
704 |
705 | - example
706 |
707 | ```tsx
708 | // Counter.tsx
709 | import React, { useReducer } from "react";
710 |
711 | const INCREMENT = "INCREMENT";
712 | const INCREMENTBYAMOUNT = "INCREMENTBYAMOUNT";
713 | const RESET = "RESET";
714 | const DECREMENT = "DECREMENT";
715 |
716 | const initialState = { count: 0 };
717 | type counterState = {
718 | count: number;
719 | };
720 |
721 | type IncrementActionType = { type: typeof INCREMENT };
722 | type IncrementByAmountActionType = {
723 | type: typeof INCREMENTBYAMOUNT;
724 | payload: number;
725 | };
726 | type ResetActionType = { type: typeof RESET };
727 | type DecrementActionType = { type: typeof DECREMENT };
728 |
729 | type counterActionType =
730 | | IncrementActionType
731 | | DecrementActionType
732 | | ResetActionType
733 | | IncrementByAmountActionType;
734 |
735 | const reducer = (state: counterState, action: counterActionType) => {
736 | switch (action.type) {
737 | case INCREMENT:
738 | return { count: state.count + 1 };
739 | case INCREMENTBYAMOUNT:
740 | return { count: state.count + action.payload };
741 | case RESET:
742 | return { count: 0 };
743 | case DECREMENT:
744 | return { count: state.count - 1 };
745 | default:
746 | throw new Error();
747 | }
748 | };
749 |
750 | const Counter = () => {
751 | const [state, dispatch] = useReducer(reducer, initialState);
752 | return (
753 |
754 |
Count : {state.count}
755 |
762 |
769 |
776 |
783 |
784 | );
785 | };
786 |
787 | export default Counter;
788 | ```
789 |
--------------------------------------------------------------------------------