├── src ├── 3-useContext │ ├── starter │ │ └── 1-useContext-basics.js │ └── final │ │ ├── ChildComponent.js │ │ ├── 1-useContext-basics.js │ │ └── SubChildComponent.js ├── 4-useReducer │ ├── starter │ │ └── 1-useRedcuer-basics.js │ └── final │ │ ├── 1-useRedcuer-basics.js │ │ └── 2-useReducer-advanced.js ├── 8-customHooks │ ├── starter │ │ └── index.js │ └── final │ │ ├── example1 │ │ ├── usePageTitle.js │ │ ├── PageTitleOne.js │ │ └── PageTitleTwo.js │ │ ├── example2 │ │ ├── useCounter.js │ │ ├── FirstCounter.js │ │ └── SecondCounter.js │ │ └── example3 │ │ ├── FirstApi.js │ │ ├── SecondApi.js │ │ └── useFetch.js ├── components │ ├── Logout.js │ ├── Contact.js │ ├── NewProjects.js │ ├── FeaturedProjects.js │ ├── PrivateRoute.js │ ├── NotFound.js │ ├── Success.js │ ├── Projects.js │ ├── Home.js │ ├── UserDetails.js │ ├── auth.js │ ├── Users.js │ ├── Login.js │ ├── Navbar.js │ └── usersData.js ├── 5-useRef │ ├── starter │ │ └── 1-useRef-example.js │ └── final │ │ ├── 1-useRef-example.js │ │ └── 2-useRef-example2.js ├── 6-useMemo │ ├── starter │ │ └── 1-useMemo-ex1.js │ └── final │ │ └── 1-useMemo-ex1.js ├── 7-useCallback │ ├── starter │ │ └── ParentComp.js │ └── final │ │ ├── Title.js │ │ ├── Button.js │ │ ├── Count.js │ │ └── ParentComp.js ├── 2-useEffect │ ├── starter │ │ └── 1-useEffect-basics.js │ └── final │ │ ├── 1-useEffect-basics.js │ │ ├── 2-useEffect-advanced.js │ │ ├── 3-useEffect-example-1.js │ │ └── 4-useEffect-example-2.js ├── 1-useState │ ├── starter │ │ └── 1-useState-basics.js │ └── final │ │ ├── 1-useState-basics.js │ │ ├── 3-useState-example-1.js │ │ ├── 2-useState-advanced.js │ │ ├── 4-useState-example-2.js │ │ └── 5-useState-example-3.js ├── Fragments │ ├── starter │ │ └── index.js │ └── final │ │ ├── Columns.js │ │ ├── index.js │ │ └── Table.js ├── HigherOrderComp │ ├── starter │ │ └── ClickCounter.js │ └── final │ │ ├── HoverCounter.js │ │ ├── ClickCounter.js │ │ └── enhancedCounter.js ├── App.js ├── index.js ├── context │ ├── userContext.js │ └── mainDataContext.js ├── index.css └── RoutingApp.js ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json └── index.html ├── .gitignore ├── package.json └── README.md /src/3-useContext/starter/1-useContext-basics.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/4-useReducer/starter/1-useRedcuer-basics.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/racharlasrikanth/react-full-course/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/racharlasrikanth/react-full-course/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/racharlasrikanth/react-full-course/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/8-customHooks/starter/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function index() { 4 | return
index
; 5 | } 6 | 7 | export default index; 8 | -------------------------------------------------------------------------------- /src/components/Logout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function Logout() { 4 | return
Logout Page
; 5 | } 6 | 7 | export default Logout; 8 | -------------------------------------------------------------------------------- /src/5-useRef/starter/1-useRef-example.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Starter = () => { 4 | return
Starter
; 5 | }; 6 | 7 | export default Starter; 8 | -------------------------------------------------------------------------------- /src/6-useMemo/starter/1-useMemo-ex1.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Starter = () => { 4 | return
Starter
; 5 | }; 6 | 7 | export default Starter; 8 | -------------------------------------------------------------------------------- /src/7-useCallback/starter/ParentComp.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const ParentComp = () => { 4 | return
ParentComp
; 5 | }; 6 | 7 | export default ParentComp; 8 | -------------------------------------------------------------------------------- /src/2-useEffect/starter/1-useEffect-basics.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Starter = () => { 4 | return
Starter useEffect
; 5 | }; 6 | 7 | export default Starter; 8 | -------------------------------------------------------------------------------- /src/components/Contact.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function Contact() { 4 | return ( 5 |
6 |

Contact

7 |
8 | ); 9 | } 10 | 11 | export default Contact; 12 | -------------------------------------------------------------------------------- /src/components/NewProjects.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function NewProjects() { 4 | return ( 5 |
6 |

NewProjects

7 |
8 | ); 9 | } 10 | 11 | export default NewProjects; 12 | -------------------------------------------------------------------------------- /src/1-useState/starter/1-useState-basics.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Index = () => { 4 | return ( 5 |
6 |

helo index

7 |
8 | ); 9 | }; 10 | 11 | export default Index; 12 | -------------------------------------------------------------------------------- /src/7-useCallback/final/Title.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Title = () => { 4 | console.log("title rendered"); 5 | return

useCallback demo & React.memo

; 6 | }; 7 | 8 | export default React.memo(Title); 9 | -------------------------------------------------------------------------------- /src/Fragments/starter/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const index = () => { 4 | return ( 5 |
6 |

example in fragment

7 |
8 | ); 9 | }; 10 | 11 | export default index; 12 | -------------------------------------------------------------------------------- /src/Fragments/final/Columns.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function Columns() { 4 | return ( 5 | <> 6 | Name 7 | Srikanth 8 | 9 | ); 10 | } 11 | 12 | export default Columns; 13 | -------------------------------------------------------------------------------- /src/components/FeaturedProjects.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function FeaturedProjects() { 4 | return ( 5 |
6 |

FeaturedProjects

7 |
8 | ); 9 | } 10 | 11 | export default FeaturedProjects; 12 | -------------------------------------------------------------------------------- /src/HigherOrderComp/starter/ClickCounter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const ClickCounter = () => { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | }; 10 | 11 | export default ClickCounter; 12 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example1/usePageTitle.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | function usePageTitle(count) { 4 | useEffect(() => { 5 | document.title = `count - ${count}`; 6 | }, [count]); 7 | } 8 | 9 | export default usePageTitle; 10 | -------------------------------------------------------------------------------- /src/7-useCallback/final/Button.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Button = ({ children, clickHandler }) => { 4 | console.log(`${children} rendered`); 5 | return ; 6 | }; 7 | 8 | export default React.memo(Button); 9 | -------------------------------------------------------------------------------- /src/7-useCallback/final/Count.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Count = ({ text, number }) => { 4 | console.log(`${text} rendered`); 5 | return ( 6 |

7 | {text} : {number} 8 |

9 | ); 10 | }; 11 | 12 | export default React.memo(Count); 13 | -------------------------------------------------------------------------------- /src/3-useContext/final/ChildComponent.js: -------------------------------------------------------------------------------- 1 | import SubChildCompmonent from "./SubChildComponent"; 2 | 3 | const ChildComponent = () => { 4 | return ( 5 |
6 |

Child component

7 | 8 |
9 | ); 10 | }; 11 | 12 | export default ChildComponent; 13 | -------------------------------------------------------------------------------- /src/3-useContext/final/1-useContext-basics.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import ChildComponent from "./ChildComponent"; 3 | 4 | const ParentComponent = () => { 5 | return ( 6 |
7 |

useContext Parent Component

8 | 9 |
10 | ); 11 | }; 12 | 13 | export default ParentComponent; 14 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Final from "./HigherOrderComp/final/ClickCounter"; 3 | import Final2 from "./HigherOrderComp/final/HoverCounter"; 4 | 5 | function App() { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | } 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /src/Fragments/final/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const index = () => { 4 | return ( 5 | 6 |

example on fragment

7 |

8 | Lorem ipsum dolor sit, amet consectetur adipisicing elit. Deleniti, ea? 9 |

10 |
11 | ); 12 | }; 13 | 14 | export default index; 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import { BrowserRouter } from "react-router-dom"; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById("root")); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /src/HigherOrderComp/final/HoverCounter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import enhancedCounter from "./enhancedCounter"; 3 | 4 | const HoverCounter = (props) => { 5 | return ( 6 |
7 |

Hovered {props.count} times

8 |
9 | ); 10 | }; 11 | 12 | export default enhancedCounter(HoverCounter, 5); 13 | -------------------------------------------------------------------------------- /src/components/PrivateRoute.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useAuth } from "./auth"; 3 | import { Navigate } from "react-router-dom"; 4 | 5 | function PrivateRoute({ children }) { 6 | const { user } = useAuth(); 7 | 8 | if (!user) { 9 | return ; 10 | } 11 | 12 | return children; 13 | } 14 | 15 | export default PrivateRoute; 16 | -------------------------------------------------------------------------------- /src/components/NotFound.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | 4 | function NotFound() { 5 | const navigate = useNavigate(); 6 | 7 | return ( 8 |
9 |

404 NotFound

10 | 11 |
12 | ); 13 | } 14 | 15 | export default NotFound; 16 | -------------------------------------------------------------------------------- /src/components/Success.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | 4 | function Success() { 5 | const navigate = useNavigate(); 6 | 7 | return ( 8 |
9 |

Successfully Submitted

10 | 11 |
12 | ); 13 | } 14 | 15 | export default Success; 16 | -------------------------------------------------------------------------------- /src/Fragments/final/Table.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Columns from "./Columns"; 3 | 4 | function Table() { 5 | return ( 6 |
7 |

table

8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | ); 17 | } 18 | 19 | export default Table; 20 | -------------------------------------------------------------------------------- /src/HigherOrderComp/final/ClickCounter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import enhancedCounter from "./enhancedCounter"; 3 | 4 | const ClickCounter = (props) => { 5 | return ( 6 |
7 | 10 |
11 | ); 12 | }; 13 | 14 | export default enhancedCounter(ClickCounter, 10); 15 | -------------------------------------------------------------------------------- /src/context/userContext.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const initialState = { 4 | firstName: "emma", 5 | lastName: "watson", 6 | email: "emma@gmail.com", 7 | }; 8 | 9 | export const UserContext = React.createContext(); 10 | 11 | export const UserContextProvider = ({ children }) => { 12 | return ( 13 | {children} 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/components/Projects.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link, Outlet } from "react-router-dom"; 3 | 4 | function Projects() { 5 | return ( 6 |
7 |

Projects

8 | 12 | 13 |
14 | ); 15 | } 16 | 17 | export default Projects; 18 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example1/PageTitleOne.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import usePageTitle from "./usePageTitle"; 3 | 4 | const PageTitleOne = () => { 5 | const [count, setCount] = useState(0); 6 | 7 | usePageTitle(count); 8 | 9 | return ( 10 |
11 | 12 |
13 | ); 14 | }; 15 | 16 | export default PageTitleOne; 17 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example1/PageTitleTwo.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import usePageTitle from "./usePageTitle"; 3 | 4 | const PageTitleTwo = () => { 5 | const [count, setCount] = useState(0); 6 | 7 | usePageTitle(count); 8 | 9 | return ( 10 |
11 | 12 |
13 | ); 14 | }; 15 | 16 | export default PageTitleTwo; 17 | -------------------------------------------------------------------------------- /src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | 4 | function Home() { 5 | const navigate = useNavigate(); 6 | 7 | const navigateToSuccessPage = () => { 8 | navigate("/success"); 9 | }; 10 | 11 | return ( 12 |
13 |

Home

14 | 15 |
16 | ); 17 | } 18 | 19 | export default Home; 20 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example2/useCounter.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | function useCounter(initialValue = 0) { 4 | const [count, setCount] = useState(initialValue); 5 | 6 | const increment = () => { 7 | setCount(count + 1); 8 | }; 9 | 10 | const decrement = () => { 11 | setCount(count - 1); 12 | }; 13 | 14 | const reset = () => { 15 | setCount(initialValue); 16 | }; 17 | 18 | return [count, increment, decrement, reset]; 19 | } 20 | 21 | export default useCounter; 22 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example2/FirstCounter.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import useCounter from "./useCounter"; 3 | 4 | const FirstCounter = () => { 5 | const [count, increment, decrement, reset] = useCounter(); 6 | return ( 7 |
8 |

Count == {count}

9 |
10 | 11 | 12 | 13 |
14 |
15 | ); 16 | }; 17 | 18 | export default FirstCounter; 19 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example2/SecondCounter.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import useCounter from "./useCounter"; 3 | 4 | const SecondCounter = () => { 5 | const [count, increment, decrement, reset] = useCounter(10); 6 | 7 | return ( 8 |
9 |

Count == {count}

10 |
11 | 12 | 13 | 14 |
15 |
16 | ); 17 | }; 18 | 19 | export default SecondCounter; 20 | -------------------------------------------------------------------------------- /src/context/mainDataContext.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const initialState = [ 4 | { 5 | firstName: "emma", 6 | lastName: "watson", 7 | email: "emma@gmail.com", 8 | }, 9 | { 10 | firstName: "hlo", 11 | lastName: "hsdfan", 12 | email: "helo@gmail.com", 13 | }, 14 | ]; 15 | 16 | export const MainDataContext = React.createContext(); 17 | 18 | export const MainDataContextProvider = ({ children }) => { 19 | return ( 20 | 21 | {children} 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /src/2-useEffect/final/1-useEffect-basics.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | 3 | const Final = () => { 4 | const [count, setCount] = useState(0); 5 | 6 | useEffect(() => { 7 | console.log("Hello I am coming from useEffect", count); 8 | }, []); 9 | 10 | return ( 11 |
12 |

Learn useEffect hello

13 |

{count}

14 | 21 |
22 | ); 23 | }; 24 | 25 | export default Final; 26 | -------------------------------------------------------------------------------- /src/HigherOrderComp/final/enhancedCounter.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const enhancedCounter = (OriginalComponent, incrementNumber) => { 4 | const NewComponent = (props) => { 5 | const [count, setCount] = useState(0); 6 | 7 | const incrementCount = () => { 8 | setCount(count + incrementNumber); 9 | }; 10 | 11 | return ( 12 | 17 | ); 18 | }; 19 | 20 | return NewComponent; 21 | }; 22 | 23 | export default enhancedCounter; 24 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/components/UserDetails.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useParams } from "react-router-dom"; 3 | import userData from "./usersData"; 4 | 5 | function UserDetails() { 6 | const { userId } = useParams(); 7 | 8 | const userDetailsData = userData.find((eachUser) => eachUser.id == userId); 9 | 10 | return ( 11 |
12 |

UserDetails

13 | 14 |

{userDetailsData.name}

15 |

{userDetailsData.email}

16 |

{userDetailsData.username}

17 |

{userDetailsData.phone}

18 |
19 | ); 20 | } 21 | 22 | export default UserDetails; 23 | -------------------------------------------------------------------------------- /src/components/auth.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from "react"; 2 | 3 | const AuthContext = React.createContext(); 4 | 5 | export const AuthProvider = ({ children }) => { 6 | const [user, setUser] = useState(null); 7 | 8 | const login = (username) => { 9 | setUser(username); 10 | }; 11 | 12 | const logout = () => { 13 | setUser(null); 14 | }; 15 | 16 | return ( 17 | 18 | {children} 19 | 20 | ); 21 | }; 22 | 23 | export const useAuth = () => { 24 | return useContext(AuthContext); 25 | }; 26 | -------------------------------------------------------------------------------- /src/3-useContext/final/SubChildComponent.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { UserContext } from "../../context/userContext"; 3 | import { MainDataContext } from "../../context/mainDataContext"; 4 | 5 | const SubChildCompmonent = () => { 6 | const data = useContext(UserContext); 7 | const mainData = useContext(MainDataContext); 8 | 9 | console.log(mainData); 10 | 11 | const { firstName, lastName, email } = data; 12 | 13 | return ( 14 |
15 |

Sub child component

16 |
firstName:{firstName}
17 |
lastname:{lastName}
18 |
email:{email}
19 |
20 | ); 21 | }; 22 | 23 | export default SubChildCompmonent; 24 | -------------------------------------------------------------------------------- /src/5-useRef/final/1-useRef-example.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from "react"; 2 | 3 | const Final = () => { 4 | const [firstName, setFirstName] = useState(""); 5 | const renderCount = useRef(1); 6 | 7 | useEffect(() => { 8 | renderCount.current = renderCount.current + 1; 9 | }); 10 | 11 | return ( 12 | <> 13 | { 18 | setFirstName(e.target.value); 19 | }} 20 | /> 21 |
Typing: {firstName}
22 |
Component renderd {renderCount.current} times
23 | 24 | ); 25 | }; 26 | 27 | export default Final; 28 | -------------------------------------------------------------------------------- /src/components/Users.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import usersData from "./usersData"; 4 | 5 | function Users() { 6 | return ( 7 |
8 |

Users

9 |
10 | {usersData.map((eachUser) => { 11 | const { id, name, email } = eachUser; 12 | return ( 13 | 14 |
15 |

{name}

16 |
{email}
17 |
18 | 19 | ); 20 | })} 21 |
22 |
23 | ); 24 | } 25 | 26 | export default Users; 27 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example3/FirstApi.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import useFetch from "./useFetch"; 3 | 4 | const URL = "https://jsonplaceholder.typicode.com/users"; 5 | 6 | const FirstApi = () => { 7 | const [userData, loading, isError] = useFetch(URL); 8 | if (isError) { 9 | return

something was happned

; 10 | } 11 | 12 | if (loading) { 13 | return

loading...

; 14 | } 15 | 16 | return ( 17 |
18 |

users

19 |
    20 | {userData.map((eachUser) => { 21 | return
  • {eachUser.username}
  • ; 22 | })} 23 |
24 |
25 | ); 26 | }; 27 | 28 | export default FirstApi; 29 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example3/SecondApi.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import useFetch from "./useFetch"; 3 | 4 | const URL = "https://jsonplaceholder.typicode.com/posts"; 5 | 6 | const SecondApi = () => { 7 | const [postsData, loading, isError] = useFetch(URL); 8 | 9 | if (isError) { 10 | return

something was happned

; 11 | } 12 | 13 | if (loading) { 14 | return

loading...

; 15 | } 16 | 17 | return ( 18 |
19 |

posts

20 |
    21 | {postsData.map((eachUser) => { 22 | return
  • {eachUser.title}
  • ; 23 | })} 24 |
25 |
26 | ); 27 | }; 28 | 29 | export default SecondApi; 30 | -------------------------------------------------------------------------------- /src/5-useRef/final/2-useRef-example2.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from "react"; 2 | 3 | const Final = () => { 4 | const [firstName, setFirstName] = useState(""); 5 | const inputDom = useRef(""); 6 | 7 | useEffect(() => { 8 | console.log(inputDom); 9 | }); 10 | 11 | const focus = () => { 12 | inputDom.current.focus(); 13 | }; 14 | 15 | return ( 16 | <> 17 | { 23 | setFirstName(e.target.value); 24 | }} 25 | /> 26 |
Typing: {firstName}
27 | 28 | 29 | ); 30 | }; 31 | 32 | export default Final; 33 | -------------------------------------------------------------------------------- /src/8-customHooks/final/example3/useFetch.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | 3 | function useFetch(URL) { 4 | const [data, setData] = useState([]); 5 | const [loading, setLoading] = useState(false); 6 | const [isError, setIsError] = useState(false); 7 | 8 | const makeAPICall = async () => { 9 | setLoading(true); 10 | setIsError(false); 11 | try { 12 | const response = await fetch(URL); 13 | const comingData = await response.json(); 14 | setData(comingData); 15 | setLoading(false); 16 | } catch (error) { 17 | setIsError(true); 18 | setLoading(false); 19 | } 20 | }; 21 | 22 | useEffect(() => { 23 | makeAPICall(URL); 24 | }, []); 25 | 26 | return [data, loading, isError]; 27 | } 28 | 29 | export default useFetch; 30 | -------------------------------------------------------------------------------- /src/1-useState/final/1-useState-basics.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Index = () => { 4 | const [count, setCount] = useState(0); 5 | 6 | const incrementCount = () => { 7 | setCount((prevCount) => { 8 | return prevCount + 1; 9 | }); 10 | // setCount((prevCount) => { 11 | // return prevCount + 1; 12 | // }); 13 | setCount((prevCount) => prevCount + 1); 14 | }; 15 | 16 | const decrementCount = () => { 17 | setCount((prevCount) => prevCount - 1); 18 | setCount((prevCount) => prevCount - 1); 19 | }; 20 | 21 | return ( 22 |
23 | 24 | Count: {count} 25 | 26 |
27 | ); 28 | }; 29 | 30 | export default Index; 31 | -------------------------------------------------------------------------------- /src/components/Login.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { useAuth } from "./auth"; 3 | import { useNavigate } from "react-router-dom"; 4 | 5 | function Login() { 6 | const navigate = useNavigate(); 7 | const { login } = useAuth(); 8 | const [name, setName] = useState(""); 9 | 10 | return ( 11 |
12 |

Login

13 | 14 | setName(e.target.value)} 21 | /> 22 | 30 |
31 | ); 32 | } 33 | 34 | export default Login; 35 | -------------------------------------------------------------------------------- /src/7-useCallback/final/ParentComp.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useCallback } from "react"; 2 | import Button from "./Button"; 3 | import Title from "./Title"; 4 | import Count from "./Count"; 5 | 6 | const ParentComp = () => { 7 | const [age, setAge] = useState(0); 8 | const [salary, setSalary] = useState(7000); 9 | 10 | const incrementAge = useCallback(() => { 11 | setAge(age + 1); 12 | }, [age]); 13 | 14 | const incrementSalary = useCallback(() => { 15 | setSalary(salary + 1000); 16 | }, [salary]); 17 | 18 | return ( 19 | <> 20 | 21 | <Count text={"age"} number={age} /> 22 | <Button clickHandler={incrementAge}>increment age</Button> 23 | <Count text={"salary"} number={salary} /> 24 | <Button clickHandler={incrementSalary}>increment salary</Button> 25 | </> 26 | ); 27 | }; 28 | 29 | export default ParentComp; 30 | -------------------------------------------------------------------------------- /src/2-useEffect/final/2-useEffect-advanced.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | 3 | const Final = () => { 4 | const [count, setCount] = useState(0); 5 | const [pageWidth, setPageWidth] = useState(window.innerWidth); 6 | 7 | useEffect(() => { 8 | const resizeHandler = () => { 9 | setPageWidth(window.innerWidth); 10 | }; 11 | window.addEventListener("resize", resizeHandler); 12 | console.log("Hello I am coming from useEffect", count); 13 | 14 | return () => { 15 | console.log("I am removing"); 16 | window.removeEventListener("resize", resizeHandler); 17 | }; 18 | }); 19 | 20 | return ( 21 | <div> 22 | <h1>Learn useEffect</h1> 23 | <h1>{pageWidth}</h1> 24 | <h1>{count}</h1> 25 | <button 26 | onClick={() => { 27 | setCount(count + 1); 28 | }} 29 | > 30 | + 31 | </button> 32 | </div> 33 | ); 34 | }; 35 | 36 | export default Final; 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-full-course", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.2.0", 10 | "react-dom": "^18.2.0", 11 | "react-router-dom": "^6.4.3", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/1-useState/final/3-useState-example-1.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Index = () => { 4 | const [showData, setShowData] = useState(false); 5 | 6 | const handleChange = () => { 7 | setShowData(!showData); 8 | }; 9 | 10 | return ( 11 | <div> 12 | <button onClick={handleChange}>{showData ? "hide" : "show"}</button> 13 | {/* {showData && ( 14 | <div className="content"> 15 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nostrum, 16 | cum. Lorem ipsum dolor sit amet consectetur adipisicing elit. Minus 17 | quaerat ipsum rem vitae soluta autem porro ex enim veritatis? 18 | Asperiores? 19 | </div> 20 | )} */} 21 | {showData ? ( 22 | <div> 23 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste quia 24 | quisquam, ullam cupiditate asperiores commodi dolorum. Tempora, ab. 25 | Molestiae libero quidem ex, dignissimos possimus assumenda itaque 26 | reiciendis quos voluptate magnam. 27 | </div> 28 | ) : ( 29 | <h3>data is hidden</h3> 30 | )} 31 | </div> 32 | ); 33 | }; 34 | 35 | export default Index; 36 | -------------------------------------------------------------------------------- /src/6-useMemo/final/1-useMemo-ex1.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useMemo, useEffect } from "react"; 2 | 3 | const Final = () => { 4 | const [number, setNumber] = useState(0); 5 | const [dark, setDark] = useState(false); 6 | const doubleNumber = useMemo(() => { 7 | return slowFunction(number); 8 | }, [number]); 9 | 10 | const themeChange = useMemo(() => { 11 | return { 12 | backgroundColor: dark ? "black" : "white", 13 | color: dark ? "white" : "black", 14 | }; 15 | }, [dark]); 16 | 17 | useEffect(() => { 18 | console.log("theme changed"); 19 | }, [themeChange]); 20 | 21 | return ( 22 | <> 23 | <div> 24 | <input 25 | type="number" 26 | name="number" 27 | id="number" 28 | value={number} 29 | onChange={(e) => setNumber(Number(e.target.value))} 30 | /> 31 | </div> 32 | <br /> 33 | <div> 34 | <button onClick={() => setDark(!dark)}>change theme</button> 35 | </div> 36 | <h2 style={themeChange}>the number : {doubleNumber}</h2> 37 | </> 38 | ); 39 | }; 40 | 41 | const slowFunction = (number) => { 42 | for (let index = 0; index < 1000000000; index++) {} 43 | console.log("slow fun running"); 44 | return number * 2; 45 | }; 46 | 47 | export default Final; 48 | -------------------------------------------------------------------------------- /src/components/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NavLink } from "react-router-dom"; 3 | import { useAuth } from "./auth"; 4 | 5 | function Navbar() { 6 | const { user, logout } = useAuth(); 7 | 8 | const navlinkStyles = ({ isActive }) => { 9 | return { 10 | textDecoration: isActive ? "none" : "underline", 11 | fontWeight: isActive ? "bold" : "normal", 12 | }; 13 | }; 14 | 15 | return ( 16 | <div> 17 | <nav className="primary-nav"> 18 | <NavLink style={navlinkStyles} to="/"> 19 | Home 20 | </NavLink> 21 | <NavLink style={navlinkStyles} to="/about"> 22 | About 23 | </NavLink> 24 | <NavLink style={navlinkStyles} to="/contact"> 25 | Contact 26 | </NavLink> 27 | <NavLink style={navlinkStyles} to="/projects"> 28 | Projects 29 | </NavLink> 30 | <NavLink style={navlinkStyles} to="/users"> 31 | Users 32 | </NavLink> 33 | {user ? ( 34 | <NavLink style={navlinkStyles} to="/logout" onClick={logout}> 35 | Logout 36 | </NavLink> 37 | ) : ( 38 | <NavLink style={navlinkStyles} to="/login"> 39 | Login 40 | </NavLink> 41 | )} 42 | </nav> 43 | </div> 44 | ); 45 | } 46 | 47 | export default Navbar; 48 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | .App { 15 | text-align: center; 16 | } 17 | 18 | .cocktail-data { 19 | display: grid; 20 | grid-template-columns: 1fr; 21 | gap: 1rem; 22 | } 23 | .cocktail-data li { 24 | list-style-type: none; 25 | } 26 | .cocktail-data li img { 27 | width: 100%; 28 | max-height: 250px; 29 | object-fit: cover; 30 | } 31 | @media screen and (min-width: 769px) { 32 | .cocktail-data { 33 | gap: 2rem; 34 | grid-template-columns: 1fr 1fr 1fr; 35 | } 36 | } 37 | nav.primary-nav { 38 | padding: 20px; 39 | background-color: lightblue; 40 | } 41 | nav a { 42 | margin-right: 15px; 43 | } 44 | /* nav a.active { 45 | font-weight: bold; 46 | text-decoration: none; 47 | color: black; 48 | } */ 49 | .card-container { 50 | display: grid; 51 | grid-template-columns: 1fr; 52 | } 53 | @media screen and (min-width: 992px) { 54 | .card-container { 55 | grid-template-columns: 1fr 1fr 1fr; 56 | gap: 1rem; 57 | } 58 | } 59 | .card { 60 | background-color: lightblue; 61 | padding: 10px; 62 | } 63 | -------------------------------------------------------------------------------- /src/1-useState/final/2-useState-advanced.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Index = () => { 4 | const intialArray = [ 5 | { 6 | id: "sdhaffsdkfjas", 7 | firstName: "emma", 8 | lastName: "watson", 9 | age: 27, 10 | }, 11 | { 12 | id: "ksafewyiasere", 13 | firstName: "srikanth", 14 | lastName: "racharla", 15 | age: 24, 16 | }, 17 | { 18 | id: "35232fsf", 19 | firstName: "don", 20 | lastName: "seenu", 21 | age: 24, 22 | }, 23 | ]; 24 | const [data, setData] = useState(intialArray); 25 | console.log(data); 26 | 27 | const handleDelete = (comingId) => { 28 | const filterData = data.filter((eachItem) => { 29 | return eachItem.id !== comingId; 30 | }); 31 | setData(filterData); 32 | }; 33 | 34 | return ( 35 | <div> 36 | <ul> 37 | {data.map((eachItem, index) => { 38 | const { firstName, lastName, age, id } = eachItem; 39 | return ( 40 | <li key={index}> 41 | <div> 42 | my firstName <strong>{firstName}</strong> 43 | </div> 44 | <div> 45 | my lastName <strong> {lastName}</strong> 46 | </div> 47 | <div> 48 | my age <strong>{age}</strong> 49 | </div> 50 | <button onClick={() => handleDelete(id)}>delete me</button> 51 | </li> 52 | ); 53 | })} 54 | </ul> 55 | </div> 56 | ); 57 | }; 58 | 59 | export default Index; 60 | -------------------------------------------------------------------------------- /src/4-useReducer/final/1-useRedcuer-basics.js: -------------------------------------------------------------------------------- 1 | import React, { useReducer } from "react"; 2 | import { isDOMComponent } from "react-dom/test-utils"; 3 | 4 | const reducer = (state, action) => { 5 | if (action.type === "DELETE_PERSON") { 6 | const newPersons = state.data.filter((eachPerson) => { 7 | return eachPerson.id !== action.payload; 8 | }); 9 | return { 10 | ...state, 11 | data: newPersons, 12 | length: state.length - 1, 13 | }; 14 | } 15 | 16 | return state; 17 | }; 18 | 19 | const Final = () => { 20 | const initialState = { 21 | data: [ 22 | { id: "23432423", firstName: "srikanth", email: "srikanth@emgail.com" }, 23 | { id: "rer3", firstName: "emma", email: "emma@emgail.com" }, 24 | ], 25 | length: 2, 26 | }; 27 | 28 | const [state, dispatch] = useReducer(reducer, initialState); 29 | 30 | const handleDelete = (id) => { 31 | dispatch({ 32 | type: "DELETE_PERSON", 33 | payload: id, 34 | }); 35 | }; 36 | 37 | const handleEdit = (id) => { 38 | dispatch({ 39 | type: "UPDATE_PERSON", 40 | payload: id, 41 | }); 42 | }; 43 | 44 | return ( 45 | <div> 46 | <h1>Current users length : {state.length}</h1> 47 | {state.data.map((eachItem) => { 48 | const { id, firstName, email } = eachItem; 49 | return ( 50 | <div key={id}> 51 | <h3>{firstName}</h3> 52 | <p>{email}</p> 53 | <button onClick={() => handleDelete(id)}>delete</button> 54 | <button onClick={() => handleEdit(id)}>edit</button> 55 | </div> 56 | ); 57 | })} 58 | </div> 59 | ); 60 | }; 61 | 62 | export default Final; 63 | -------------------------------------------------------------------------------- /src/2-useEffect/final/3-useEffect-example-1.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | 3 | const URL = "https://jsonplaceholder.typicode.com/users"; 4 | 5 | const Final = () => { 6 | const [usersData, setUsersData] = useState([]); 7 | const [loading, setLoading] = useState(false); 8 | const [isError, setIsError] = useState({ status: false, msg: "" }); 9 | 10 | const fetchUsersData = async (apiURL) => { 11 | setLoading(true); 12 | setIsError({ status: false, msg: "" }); 13 | try { 14 | const response = await fetch(apiURL); 15 | const data = await response.json(); 16 | setUsersData(data); 17 | setLoading(false); 18 | setIsError({ status: false, msg: "" }); 19 | if (response.status === 404) { 20 | throw new Error("data not found"); 21 | } 22 | } catch (error) { 23 | setLoading(false); 24 | setIsError({ 25 | status: true, 26 | msg: error.message || "something went wrong, pls try again!", 27 | }); 28 | } 29 | }; 30 | 31 | useEffect(() => { 32 | fetchUsersData(URL); 33 | }, []); 34 | 35 | if (loading) { 36 | return ( 37 | <div> 38 | <h3>Loading...</h3> 39 | </div> 40 | ); 41 | } 42 | 43 | if (isError?.status) { 44 | return ( 45 | <div> 46 | <h3 style={{ color: "red" }}>{isError?.msg}</h3> 47 | </div> 48 | ); 49 | } 50 | 51 | return ( 52 | <div> 53 | <h1>useEffect example - 1</h1> 54 | <ul> 55 | {usersData.map((eachUser) => { 56 | const { id, name, email } = eachUser; 57 | return ( 58 | <li key={id}> 59 | <div>{name}</div> 60 | <div>{email}</div> 61 | </li> 62 | ); 63 | })} 64 | </ul> 65 | </div> 66 | ); 67 | }; 68 | 69 | export default Final; 70 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8" /> 5 | <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> 6 | <meta name="viewport" content="width=device-width, initial-scale=1" /> 7 | <meta name="theme-color" content="#000000" /> 8 | <meta 9 | name="description" 10 | content="Web site created using create-react-app" 11 | /> 12 | <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> 13 | <!-- 14 | manifest.json provides metadata used when your web app is installed on a 15 | user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ 16 | --> 17 | <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> 18 | <!-- 19 | Notice the use of %PUBLIC_URL% in the tags above. 20 | It will be replaced with the URL of the `public` folder during the build. 21 | Only files inside the `public` folder can be referenced from the HTML. 22 | 23 | Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will 24 | work correctly both with client-side routing and a non-root public URL. 25 | Learn how to configure a non-root public URL by running `npm run build`. 26 | --> 27 | <title>React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/RoutingApp.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "./components/Navbar"; 3 | import Home from "./components/Home"; 4 | // import About from "./components/About"; 5 | import Contact from "./components/Contact"; 6 | import { Routes, Route } from "react-router-dom"; 7 | import Success from "./components/Success"; 8 | import NotFound from "./components/NotFound"; 9 | import Projects from "./components/Projects"; 10 | import FeaturedProjects from "./components/FeaturedProjects"; 11 | import NewProjects from "./components/NewProjects.js"; 12 | import Users from "./components/Users"; 13 | import UserDetails from "./components/UserDetails"; 14 | import { AuthProvider } from "./components/auth"; 15 | import Login from "./components/Login"; 16 | import Logout from "./components/Logout"; 17 | import PrivateRoute from "./components/PrivateRoute"; 18 | 19 | const LazyAbout = React.lazy(() => import("./components/About")); 20 | 21 | function App() { 22 | return ( 23 | 24 | 25 | 26 | } /> 27 | 31 | 32 | 33 | } 34 | /> 35 | } /> 36 | } /> 37 | }> 38 | } /> 39 | } /> 40 | } /> 41 | 42 | 46 | 47 | 48 | } 49 | /> 50 | } /> 51 | } /> 52 | } /> 53 | } /> 54 | 55 | 56 | ); 57 | } 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /src/2-useEffect/final/4-useEffect-example-2.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | 3 | const URL = "https://www.thecocktaildb.com/api/json/v1/1/search.php?s="; 4 | 5 | const Final = () => { 6 | const [drinksData, setDrinksData] = useState([]); 7 | const [searchTerm, setSearchTerm] = useState(""); 8 | const [loading, setLoading] = useState(false); 9 | const [isError, setIsError] = useState({ status: false, msg: "" }); 10 | 11 | const fetchDrink = async (apiURL) => { 12 | setLoading(true); 13 | setIsError({ status: false, msg: "" }); 14 | try { 15 | const response = await fetch(apiURL); 16 | const { drinks } = await response.json(); 17 | setDrinksData(drinks); 18 | setLoading(false); 19 | setIsError({ status: false, msg: "" }); 20 | if (!drinks) { 21 | throw new Error("data not found"); 22 | } 23 | } catch (error) { 24 | console.log(error); 25 | setLoading(false); 26 | setIsError({ 27 | status: true, 28 | msg: error.message || "something went wrong...", 29 | }); 30 | } 31 | }; 32 | 33 | useEffect(() => { 34 | const correctURL = `${URL}${searchTerm}`; 35 | fetchDrink(correctURL); 36 | }, [searchTerm]); 37 | 38 | return ( 39 |
40 |
41 | setSearchTerm(e.target.value)} 48 | /> 49 |
50 | 51 |
52 | {loading && !isError?.status &&

Loading...

} 53 | {isError?.status &&

{isError.msg}

} 54 | {!loading && !isError?.status && ( 55 |
    56 | {drinksData.map((eachDrink) => { 57 | const { idDrink, strDrink, strDrinkThumb } = eachDrink; 58 | return ( 59 |
  • 60 |
    61 | {strDrink} 62 |
    63 |
    64 |

    {strDrink}

    65 |
    66 |
  • 67 | ); 68 | })} 69 |
70 | )} 71 |
72 | ); 73 | }; 74 | 75 | export default Final; 76 | -------------------------------------------------------------------------------- /src/1-useState/final/4-useState-example-2.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Index = () => { 4 | const [firstName, setFirstName] = useState(""); 5 | const [email, setEmail] = useState(""); 6 | const [password, setPassword] = useState(""); 7 | 8 | // const changeFirstName = (e) => { 9 | // setFirstName(e.target.value); 10 | // }; 11 | 12 | // const changeEmail = (e) => { 13 | // setEmail(e.target.value); 14 | // }; 15 | 16 | // const changePassword = (e) => { 17 | // setPassword(e.target.value); 18 | // }; 19 | 20 | // const handleInputChange = (e, name) => { 21 | // if (name === "firstName") { 22 | // setFirstName(e.target.value); 23 | // } else if (name === "email") { 24 | // setEmail(e.target.value); 25 | // } else if (name === "password") { 26 | // setPassword(e.target.value); 27 | // } 28 | // }; 29 | 30 | const handleSubmit = (e) => { 31 | e.preventDefault(); 32 | let userObj = { 33 | firstName: firstName, 34 | email: email, 35 | password: password, 36 | }; 37 | console.log(userObj); 38 | }; 39 | 40 | return ( 41 |
42 |
43 |
44 | setFirstName(e.target.value)} 51 | /> 52 |
53 |
54 |
55 | setEmail(e.target.value)} 62 | /> 63 |
64 |
65 |
66 | setPassword(e.target.value)} 73 | /> 74 |
75 |
76 | 77 |
78 |
79 |
80 | ); 81 | }; 82 | 83 | export default Index; 84 | -------------------------------------------------------------------------------- /src/1-useState/final/5-useState-example-3.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Index = () => { 4 | const [list, setList] = useState([]); 5 | const [message, setMessage] = useState({ 6 | text: "", 7 | id: "", 8 | }); 9 | const [editingItem, setEditingItem] = useState({ 10 | id: "", 11 | isEditing: false, 12 | }); 13 | 14 | const changeMessage = (e) => { 15 | setMessage({ 16 | ...message, 17 | text: e.target.value, 18 | }); 19 | }; 20 | 21 | const handleSubmit = (e) => { 22 | e.preventDefault(); 23 | let newTodo = { 24 | text: message.text, 25 | id: new Date().getTime().toString(), 26 | }; 27 | setList([...list, newTodo]); 28 | setMessage({ 29 | text: "", 30 | id: "", 31 | }); 32 | }; 33 | 34 | const handleDelete = (id) => { 35 | let newTodos = list.filter((eachItem) => { 36 | return eachItem.id !== id; 37 | }); 38 | setList(newTodos); 39 | }; 40 | 41 | const changeEditState = (id) => { 42 | setEditingItem({ 43 | ...editingItem, 44 | id: id, 45 | isEditing: true, 46 | }); 47 | let editableItem = list.find((eachItem) => eachItem.id === id); 48 | setMessage({ 49 | ...message, 50 | text: editableItem.text, 51 | id: editableItem.id, 52 | }); 53 | }; 54 | 55 | const handleEdit = (e) => { 56 | e.preventDefault(); 57 | console.log("previous todos", list); 58 | let newTodos = list.map((eachItem) => { 59 | if (eachItem.id === editingItem.id) { 60 | return { 61 | text: message.text, 62 | id: editingItem.id, 63 | }; 64 | } else { 65 | return eachItem; 66 | } 67 | }); 68 | setList(newTodos); 69 | setMessage({ 70 | text: "", 71 | id: "", 72 | }); 73 | setEditingItem({ 74 | id: "", 75 | isEditing: false, 76 | }); 77 | }; 78 | 79 | return ( 80 |
81 |
82 | 90 | {editingItem.isEditing ? ( 91 | 94 | ) : ( 95 | 98 | )} 99 |
100 |
101 | {list.length === 0 &&

There is no items in the list

} 102 |
    103 | {list.map((eachItem) => { 104 | const { text, id } = eachItem; 105 | return ( 106 |
  • 107 | {text} 108 | 109 | 110 |
  • 111 | ); 112 | })} 113 |
114 |
115 | ); 116 | }; 117 | 118 | export default Index; 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /src/4-useReducer/final/2-useReducer-advanced.js: -------------------------------------------------------------------------------- 1 | import React, { useReducer, useEffect, useState } from "react"; 2 | 3 | const reducer = (state, action) => { 4 | if (action.type === "UPDATE_USERS_DATA") { 5 | return { 6 | ...state, 7 | usersData: action.payload, 8 | }; 9 | } 10 | if (action.type === "LOADING") { 11 | return { 12 | ...state, 13 | isLoading: action.payload, 14 | }; 15 | } 16 | 17 | if (action.type === "DELETE_USER") { 18 | const newUsers = state.usersData.filter( 19 | (eachUser) => eachUser.id !== action.payload 20 | ); 21 | return { 22 | ...state, 23 | usersData: newUsers, 24 | }; 25 | } 26 | 27 | if (action.type === "ONCLICK_EDIT") { 28 | return { 29 | ...state, 30 | isEditing: action.payload, 31 | }; 32 | } 33 | 34 | if (action.type === "UPDATE_USER") { 35 | const newUsers = state.usersData.map((eachUser) => { 36 | if (eachUser.id === action.payload.id) { 37 | return { 38 | id: action.payload.id, 39 | name: action.payload.name, 40 | email: action.payload.email, 41 | }; 42 | } else { 43 | return eachUser; 44 | } 45 | }); 46 | return { 47 | ...state, 48 | usersData: newUsers, 49 | }; 50 | } 51 | 52 | return state; 53 | }; 54 | 55 | const Final = () => { 56 | const fetchUsersData = async (URL) => { 57 | dispatch({ type: "LOADING", payload: true }); 58 | dispatch({ type: "ERROR", payload: { status: false, msg: "" } }); 59 | try { 60 | const response = await fetch(URL); 61 | const data = await response.json(); 62 | dispatch({ type: "UPDATE_USERS_DATA", payload: data }); 63 | dispatch({ type: "LOADING", payload: false }); 64 | dispatch({ type: "ERROR", payload: { status: false, msg: "" } }); 65 | } catch (error) { 66 | console.log(error); 67 | dispatch({ type: "LOADING", payload: false }); 68 | dispatch({ 69 | type: "ERROR", 70 | payload: { status: true, msg: error.message }, 71 | }); 72 | } 73 | }; 74 | 75 | useEffect(() => { 76 | fetchUsersData("https://jsonplaceholder.typicode.com/users"); 77 | }, []); 78 | 79 | const initialState = { 80 | usersData: [], 81 | isLoading: false, 82 | isError: { status: false, msg: "" }, 83 | isEditing: { status: false, id: "", name: "", email: "" }, 84 | }; 85 | 86 | const [state, dispatch] = useReducer(reducer, initialState); 87 | 88 | const handleDelete = (id) => { 89 | dispatch({ type: "DELETE_USER", payload: id }); 90 | }; 91 | 92 | const updateData = (id, name, email) => { 93 | dispatch({ 94 | type: "UPDATE_USER", 95 | payload: { 96 | id, 97 | name, 98 | email, 99 | }, 100 | }); 101 | dispatch({ 102 | type: "ONCLICK_EDIT", 103 | payload: { status: false, id: "", name: "", email: "" }, 104 | }); 105 | }; 106 | 107 | if (state.isLoading) { 108 | return ( 109 |
110 |

Loading...

111 |
112 | ); 113 | } 114 | 115 | return ( 116 |
117 |

Users Information

118 | {state.isEditing?.status && ( 119 | 125 | )} 126 | {state.usersData.map((eachUser) => { 127 | const { id, name, email } = eachUser; 128 | return ( 129 |
130 |

{name}

131 |

{email}

132 | 133 | 143 |
144 | ); 145 | })} 146 |
147 | ); 148 | }; 149 | 150 | const EditFormContainer = ({ id, comingTitle, comingEmail, updateData }) => { 151 | const [title, setTitle] = useState(comingTitle || ""); 152 | const [email, setEmail] = useState(comingEmail || ""); 153 | 154 | return ( 155 | <> 156 |
157 | setTitle(e.target.value)} 163 | /> 164 | setEmail(e.target.value)} 170 | /> 171 | 174 |
175 | 176 | ); 177 | }; 178 | 179 | export default Final; 180 | -------------------------------------------------------------------------------- /src/components/usersData.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | id: 1, 4 | name: "Leanne Graham", 5 | username: "Bret", 6 | email: "Sincere@april.biz", 7 | address: { 8 | street: "Kulas Light", 9 | suite: "Apt. 556", 10 | city: "Gwenborough", 11 | zipcode: "92998-3874", 12 | geo: { 13 | lat: "-37.3159", 14 | lng: "81.1496", 15 | }, 16 | }, 17 | phone: "1-770-736-8031 x56442", 18 | website: "hildegard.org", 19 | company: { 20 | name: "Romaguera-Crona", 21 | catchPhrase: "Multi-layered client-server neural-net", 22 | bs: "harness real-time e-markets", 23 | }, 24 | }, 25 | { 26 | id: 2, 27 | name: "Ervin Howell", 28 | username: "Antonette", 29 | email: "Shanna@melissa.tv", 30 | address: { 31 | street: "Victor Plains", 32 | suite: "Suite 879", 33 | city: "Wisokyburgh", 34 | zipcode: "90566-7771", 35 | geo: { 36 | lat: "-43.9509", 37 | lng: "-34.4618", 38 | }, 39 | }, 40 | phone: "010-692-6593 x09125", 41 | website: "anastasia.net", 42 | company: { 43 | name: "Deckow-Crist", 44 | catchPhrase: "Proactive didactic contingency", 45 | bs: "synergize scalable supply-chains", 46 | }, 47 | }, 48 | { 49 | id: 3, 50 | name: "Clementine Bauch", 51 | username: "Samantha", 52 | email: "Nathan@yesenia.net", 53 | address: { 54 | street: "Douglas Extension", 55 | suite: "Suite 847", 56 | city: "McKenziehaven", 57 | zipcode: "59590-4157", 58 | geo: { 59 | lat: "-68.6102", 60 | lng: "-47.0653", 61 | }, 62 | }, 63 | phone: "1-463-123-4447", 64 | website: "ramiro.info", 65 | company: { 66 | name: "Romaguera-Jacobson", 67 | catchPhrase: "Face to face bifurcated interface", 68 | bs: "e-enable strategic applications", 69 | }, 70 | }, 71 | { 72 | id: 4, 73 | name: "Patricia Lebsack", 74 | username: "Karianne", 75 | email: "Julianne.OConner@kory.org", 76 | address: { 77 | street: "Hoeger Mall", 78 | suite: "Apt. 692", 79 | city: "South Elvis", 80 | zipcode: "53919-4257", 81 | geo: { 82 | lat: "29.4572", 83 | lng: "-164.2990", 84 | }, 85 | }, 86 | phone: "493-170-9623 x156", 87 | website: "kale.biz", 88 | company: { 89 | name: "Robel-Corkery", 90 | catchPhrase: "Multi-tiered zero tolerance productivity", 91 | bs: "transition cutting-edge web services", 92 | }, 93 | }, 94 | { 95 | id: 5, 96 | name: "Chelsey Dietrich", 97 | username: "Kamren", 98 | email: "Lucio_Hettinger@annie.ca", 99 | address: { 100 | street: "Skiles Walks", 101 | suite: "Suite 351", 102 | city: "Roscoeview", 103 | zipcode: "33263", 104 | geo: { 105 | lat: "-31.8129", 106 | lng: "62.5342", 107 | }, 108 | }, 109 | phone: "(254)954-1289", 110 | website: "demarco.info", 111 | company: { 112 | name: "Keebler LLC", 113 | catchPhrase: "User-centric fault-tolerant solution", 114 | bs: "revolutionize end-to-end systems", 115 | }, 116 | }, 117 | { 118 | id: 6, 119 | name: "Mrs. Dennis Schulist", 120 | username: "Leopoldo_Corkery", 121 | email: "Karley_Dach@jasper.info", 122 | address: { 123 | street: "Norberto Crossing", 124 | suite: "Apt. 950", 125 | city: "South Christy", 126 | zipcode: "23505-1337", 127 | geo: { 128 | lat: "-71.4197", 129 | lng: "71.7478", 130 | }, 131 | }, 132 | phone: "1-477-935-8478 x6430", 133 | website: "ola.org", 134 | company: { 135 | name: "Considine-Lockman", 136 | catchPhrase: "Synchronised bottom-line interface", 137 | bs: "e-enable innovative applications", 138 | }, 139 | }, 140 | { 141 | id: 7, 142 | name: "Kurtis Weissnat", 143 | username: "Elwyn.Skiles", 144 | email: "Telly.Hoeger@billy.biz", 145 | address: { 146 | street: "Rex Trail", 147 | suite: "Suite 280", 148 | city: "Howemouth", 149 | zipcode: "58804-1099", 150 | geo: { 151 | lat: "24.8918", 152 | lng: "21.8984", 153 | }, 154 | }, 155 | phone: "210.067.6132", 156 | website: "elvis.io", 157 | company: { 158 | name: "Johns Group", 159 | catchPhrase: "Configurable multimedia task-force", 160 | bs: "generate enterprise e-tailers", 161 | }, 162 | }, 163 | { 164 | id: 8, 165 | name: "Nicholas Runolfsdottir V", 166 | username: "Maxime_Nienow", 167 | email: "Sherwood@rosamond.me", 168 | address: { 169 | street: "Ellsworth Summit", 170 | suite: "Suite 729", 171 | city: "Aliyaview", 172 | zipcode: "45169", 173 | geo: { 174 | lat: "-14.3990", 175 | lng: "-120.7677", 176 | }, 177 | }, 178 | phone: "586.493.6943 x140", 179 | website: "jacynthe.com", 180 | company: { 181 | name: "Abernathy Group", 182 | catchPhrase: "Implemented secondary concept", 183 | bs: "e-enable extensible e-tailers", 184 | }, 185 | }, 186 | { 187 | id: 9, 188 | name: "Glenna Reichert", 189 | username: "Delphine", 190 | email: "Chaim_McDermott@dana.io", 191 | address: { 192 | street: "Dayna Park", 193 | suite: "Suite 449", 194 | city: "Bartholomebury", 195 | zipcode: "76495-3109", 196 | geo: { 197 | lat: "24.6463", 198 | lng: "-168.8889", 199 | }, 200 | }, 201 | phone: "(775)976-6794 x41206", 202 | website: "conrad.com", 203 | company: { 204 | name: "Yost and Sons", 205 | catchPhrase: "Switchable contextually-based project", 206 | bs: "aggregate real-time technologies", 207 | }, 208 | }, 209 | { 210 | id: 10, 211 | name: "Clementina DuBuque", 212 | username: "Moriah.Stanton", 213 | email: "Rey.Padberg@karina.biz", 214 | address: { 215 | street: "Kattie Turnpike", 216 | suite: "Suite 198", 217 | city: "Lebsackbury", 218 | zipcode: "31428-2261", 219 | geo: { 220 | lat: "-38.2386", 221 | lng: "57.2232", 222 | }, 223 | }, 224 | phone: "024-648-3804", 225 | website: "ambrose.net", 226 | company: { 227 | name: "Hoeger LLC", 228 | catchPhrase: "Centralized empowering task-force", 229 | bs: "target end-to-end models", 230 | }, 231 | }, 232 | ]; 233 | --------------------------------------------------------------------------------