├── .gitignore ├── Chapter02 ├── addEventListener.html ├── appPassingProps.jsx ├── arrowFunctions.jsx ├── authorFragment.jsx ├── automaticBatching.jsx ├── bindingConstructor.jsx ├── citySearch.jsx ├── classComponent.jsx ├── consumeContext.jsx ├── createContext.jsx ├── employeeWithDestructuredProps.jsx ├── forwardRefDemo.jsx ├── functionComponent.jsx ├── higherOrderComponent.jsx ├── javascriptRendering.js ├── jsxRendering.jsx ├── keyProp.jsx ├── mutateNestedObject.js ├── mutateSeparateNestedObject.js ├── provideContext.jsx ├── publicClassFieldsSyntax.jsx ├── refsDemo.jsx ├── refsUsecases.jsx ├── restrictDefaultFormEvent.html ├── restrictDefaultReactEvent.jsx ├── scrollAnimation.js ├── signoutReactComponent.jsx ├── signoutReactElement.js ├── signoutReactElementObject.js ├── singoutReactElementJsx.jsx ├── syntheticEvent.jsx ├── updateStateHandler.jsx ├── updateStateObject.jsx ├── userMemoForm.jsx ├── userState.jsx ├── userStateClassComponent.jsx └── userStateNestedObject.jsx ├── Chapter03 ├── colorContextProvider.jsx ├── refContentRecreated.jsx ├── refContentSkipRecreated.jsx ├── updaterFunction.jsx ├── useCallbackSkipRerender.jsx ├── useDebugDemo.jsx ├── useEffectCorrectDependencies.jsx ├── useEffectDependencies.jsx ├── useEffectEmptyDependencies.jsx ├── useEffectFetchingData.jsx ├── useEffectSkipDependencies.jsx ├── useFetchCustomHook.jsx ├── useFetchHookConsumer.jsx ├── useImmerDemo.jsx ├── useImperativeHandleDemo.jsx ├── useMemoDemo.jsx ├── useMemoInsideLoop.jsx ├── useMemoInsideLoopFix.jsx ├── useMemoReturnObject.jsx ├── useMemoSkipRerender.jsx ├── useMemoWithDependencies.jsx ├── useMemoWithoutDependencies.jsx ├── useReducerDemo.jsx └── useStateDemo.jsx ├── Chapter04 ├── BrowserRouterAsRouter.js ├── BrowserRouterPofile.js ├── FormattedMessage.js ├── Link.js ├── aboutRouteComponent.js ├── aboutRouteElement.js ├── createBrowserRouterAbout.js ├── createBrowserRouterHome.js ├── createRoutesFromElements.js ├── notFoundErrorPages.js ├── pageRoutes.js ├── profilePageParamRoutes.js ├── useLocation.js └── useParams.js ├── Chapter05 ├── deepLayout.jsx ├── enableStrictMode.jsx ├── errorBoundaryDemo.jsx ├── errorBoundaryUsage.jsx ├── pageTransition.jsx ├── portalBubbling.html ├── portalModal.jsx ├── portalParent.jsx ├── profilerDemo.jsx ├── reactNativeNavMenu.jsx ├── strictModeInPage.jsx ├── suspenseDemo.jsx ├── tsconfig.json └── useDeferredHookAlternative.jsx ├── Chapter06 ├── ProviderWrapper.js ├── actionCreatorInsideLazyLoading.js ├── addTodoAction.js ├── applyMiddleware.js ├── citiesReducer.js ├── configureStoreWithRTK.js ├── customStoreEnhancer.js ├── dispatchAddCityAction.js ├── endpointsWithRTK.js ├── loggerMiddleware.js ├── mapDispatchToProps.js ├── mapDispatchToPropsSimplified.js ├── mapStateToProps.js ├── multipleMiddlewares.js ├── sagaFunction.js ├── storeUsageDemo.js ├── thunkActionCreator.js ├── thunkFunction.js └── todoReducer.js ├── Chapter07 ├── App.css ├── App.js ├── Home.css ├── Home.module.css ├── chapter7Snippet11.js ├── dynamicStyleColor.js ├── flexbox.js ├── homeImportCSS.js ├── homeInlineCSS.js ├── importCSSModules.js └── importSCSS.js ├── Chapter08 ├── counter.js ├── counter.test.js ├── counterApp.js └── counterApp.test.js ├── Chapter09 ├── metaAuthorTag.html ├── metaLanguageTag.html ├── metaNameTag.html ├── metaPropertyTag.html ├── metaRobotsTag.html ├── metaViewportTag.html └── titleTag.html ├── Chapter10 └── gitRepoSetup.md ├── Chapter11 └── one-stop-electronics │ ├── .gitignore │ ├── .vscode │ └── settings.json │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── App.css │ ├── App.tsx │ ├── app │ │ └── store │ │ │ ├── cart │ │ │ ├── cart.selector.ts │ │ │ ├── cart.slice.spec.ts │ │ │ ├── cart.slice.ts │ │ │ └── cart.types.ts │ │ │ ├── hooks.ts │ │ │ ├── product │ │ │ ├── product.selector.ts │ │ │ ├── product.slice.ts │ │ │ └── product.types.ts │ │ │ ├── root-reducer.ts │ │ │ ├── store.ts │ │ │ └── user │ │ │ ├── user.selector.ts │ │ │ ├── user.slice.ts │ │ │ └── user.types.ts.ts │ ├── assets │ │ ├── clear.svg │ │ ├── minus.svg │ │ ├── one-stop-electronics-tab.svg │ │ ├── one-stop-electronics.svg │ │ ├── plus.svg │ │ ├── products │ │ │ ├── apple14.png │ │ │ ├── apple_ipad10.png │ │ │ ├── galaxy_a34.png │ │ │ ├── galaxy_a54.png │ │ │ ├── galaxy_tab_s8.png │ │ │ ├── galaxytab_s9.png │ │ │ └── huawei_p30.png │ │ ├── screens │ │ │ ├── cart.png │ │ │ ├── products.png │ │ │ ├── signin.png │ │ │ └── signup.png │ │ ├── shopping-cart.svg │ │ └── user-profile-avatar.svg │ ├── backend │ │ └── firebase │ │ │ ├── api │ │ │ ├── auth.ts │ │ │ ├── db-utils.ts │ │ │ └── products-data.ts │ │ │ └── config.ts │ ├── components │ │ ├── button │ │ │ ├── button.styles.tsx │ │ │ └── button.tsx │ │ ├── categories │ │ │ ├── categories.styles.tsx │ │ │ ├── categories.tsx │ │ │ └── categories.types.tsx │ │ ├── footer │ │ │ ├── footer.styles.tsx │ │ │ └── footer.tsx │ │ ├── header │ │ │ ├── header.styles.tsx │ │ │ └── header.tsx │ │ ├── input │ │ │ ├── input.styles.tsx │ │ │ └── input.tsx │ │ ├── product │ │ │ ├── product.styles.tsx │ │ │ └── product.tsx │ │ ├── select │ │ │ ├── select.styles.tsx │ │ │ └── select.tsx │ │ └── spinner │ │ │ ├── spinner.styles.tsx │ │ │ └── spinner.tsx │ ├── constants.tsx │ ├── custom.d.ts │ ├── features │ │ ├── auth │ │ │ ├── signin │ │ │ │ ├── page.styles.tsx │ │ │ │ └── page.tsx │ │ │ └── signup │ │ │ │ ├── page.styles.tsx │ │ │ │ └── page.tsx │ │ ├── cart │ │ │ ├── cart.styles.tsx │ │ │ └── cart.tsx │ │ └── products │ │ │ ├── products.styles.tsx │ │ │ └── products.tsx │ ├── global.styles.tsx │ ├── i18n │ │ ├── locale.ts │ │ └── translations │ │ │ ├── de-DE.json │ │ │ ├── en-US.json │ │ │ └── fr-FR.json │ ├── index.css │ ├── main.tsx │ ├── setupTests.ts │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── Chapter12 ├── HomePage.js ├── HomePage.test.js ├── HomePageApp.js ├── NotFoundPage.js ├── RootLayout.js ├── SessionProvider.js ├── authoBio.json ├── authoProfile.json ├── authorBlog.json ├── buildFrontendArchitecture.md ├── coffee-restaurant │ ├── .gitignore │ ├── README.md │ ├── data │ │ ├── menu.js │ │ └── profile.js │ ├── img │ │ └── coffee-restaurant.jpg │ ├── jest.config.mjs │ ├── jsconfig.json │ ├── next.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── next.svg │ │ └── vercel.svg │ └── src │ │ └── app │ │ ├── account │ │ ├── menu │ │ │ └── page.js │ │ └── profile │ │ │ └── page.js │ │ ├── api │ │ └── auth │ │ │ └── [...nextauth] │ │ │ └── route.js │ │ ├── components │ │ ├── GlobalStyles.js │ │ ├── MainMenu.js │ │ └── Provider.js │ │ ├── favicon.ico │ │ ├── globals.css │ │ ├── graphql │ │ └── route.js │ │ ├── layout.js │ │ ├── lib │ │ └── registry.js │ │ ├── not-found.js │ │ ├── nutrition │ │ ├── page.js │ │ └── page.test.js │ │ ├── page.js │ │ ├── page.module.css │ │ ├── page.test.js │ │ ├── queries │ │ └── clientQueries.js │ │ └── utils │ │ ├── cors.js │ │ └── withApollo.js ├── cors.js ├── createGlobalStyle.js ├── envSecrets.md ├── expressBackend.js ├── gitRepoPush.md ├── gitRepoSetup.md ├── graphQLMenuProfileQueries.js ├── graphQLQuery.graphql ├── graphQLQueryMenu.graphql ├── graphQLSchema.graphql ├── graphQLSchemaAndResolvers.js ├── initializeApollo.js ├── installFrontendPackages.md ├── installTestingLibrary.md ├── jestTestWatch.md ├── jordanBrewerprofile.js ├── mainNavigation.js ├── menuCoffee.js ├── menuPage.js ├── nextAuth.js ├── nextConfig.js ├── nextJest.js ├── nutritionPage.js ├── nutritionPage.test.js └── styleSheet.js ├── LICENSE └── README.md /.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 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /Chapter02/addEventListener.html: -------------------------------------------------------------------------------- 1 |

2 | Please SignUp 3 |

4 | 5 | ; 7 | } -------------------------------------------------------------------------------- /Chapter02/authorFragment.jsx: -------------------------------------------------------------------------------- 1 | function Author() { 2 | return posts.map(post => 3 | 4 | 5 | 6 | 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/automaticBatching.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | export default function MultiState() { 4 | const [count, setCount] = useState(0); 5 | const [message, setMessage] = useState('Batching'); 6 | 7 | console.log('Application re-rendered'); 8 | const handleAsyncFetch = () => { 9 | fetch("https://jsonplaceholder.typicode.com/todos/1").then(() => { 10 | // trigger only one(1) re-render due to Automatic Batching 11 | setCount(count +1); 12 | setMessage('Automatic batching'); 13 | }); 14 | } 15 | 16 | return ( 17 | <> 18 |

{count}

19 | 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /Chapter02/bindingConstructor.jsx: -------------------------------------------------------------------------------- 1 | class User extends Component { 2 | 3 | constructor(props) { 4 | super(props); 5 | this.handleUserDetails = this.handleUserDetails.bind(this); 6 | } 7 | 8 | handleUserDetails() { 9 | console.log("Show User details"); 10 | } 11 | 12 | render() { 13 | return ; 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /Chapter02/citySearch.jsx: -------------------------------------------------------------------------------- 1 | function CitySearch() { 2 | return ( 3 |
4 |

Find city:

5 |
6 | 7 | City: 8 | 9 | 10 |
11 |
12 | ) 13 | } -------------------------------------------------------------------------------- /Chapter02/classComponent.jsx: -------------------------------------------------------------------------------- 1 | function User({ message }) { 2 | return

{`Hello, ${message}`}

; 3 | } 4 | export default User; 5 | -------------------------------------------------------------------------------- /Chapter02/consumeContext.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { UserContext } from './context'; 3 | 4 | function MyChildComponent() { 5 | const currentUser = useContext(UserContext); 6 | return {currentUser}; 7 | } -------------------------------------------------------------------------------- /Chapter02/createContext.jsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const userContext = createContext('Jonathan'); -------------------------------------------------------------------------------- /Chapter02/employeeWithDestructuredProps.jsx: -------------------------------------------------------------------------------- 1 | function Employee({ name, age, department }) { 2 | return ( 3 | <> 4 | Name: {name} 5 | Age: {age} 6 | Department: {department} 7 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /Chapter02/forwardRefDemo.jsx: -------------------------------------------------------------------------------- 1 | import { forwardRef } from 'react'; 2 | 3 | const MySingInButton = forwardRef(function MySingInButton(props, ref) { 4 | const { label, ...otherProps } = props; 5 | 6 | return ( 7 |