Category: React

  • Build a SaaS AI Platform with Next.js 13, React, Tailwind, Prisma, Stripe Full Tutorial 2023 – Study Notes

    Build a SaaS AI Platform with Next.js 13, React, Tailwind, Prisma, Stripe Full Tutorial 2023 – Study Notes

    Genius App FAQ

    What is Genius?

    Genius is a full-stack AI-powered SaaS platform offering various AI tools, including:

    • Conversation: An advanced conversational AI model similar to ChatGPT.
    • Image Generation: Creates images from text prompts.
    • Music Generation: Generates music based on your descriptions.
    • Code Generation: Produces code from given instructions.
    • Video Generation: Transforms text prompts into realistic videos.

    How do I access the Genius dashboard?

    Once you have logged in, you can access the dashboard at the URL /dashboard. Only authorized users can view the protected dashboard page.

    What is a Route Group in Next.js?

    Route groups in Next.js are specially named folders that organize your files without affecting the URL structure. For instance, a route group named (marketing) containing a page about.tsx would be accessible via /about and not /marketing/about.

    How does authentication work in Genius?

    Genius utilizes Clerk for authentication, enabling secure user login and registration. You can sign up or log in using your preferred method, such as Google.

    How can I customize the authentication flow?

    Clerk offers customization options for branding and redirect URLs. You can modify the sign-in and sign-up pages, including redirecting users to the /dashboard after successful login.

    What is the free tier usage limit?

    Free tier users have a limit of 5 generations across all AI tools. Once exceeded, a subscription to the Pro plan is required for continued usage.

    How do subscriptions work?

    Genius integrates with Stripe for managing user subscriptions. The Pro plan provides unlimited access to all AI tools. You can manage your subscription and billing details in the /settings page.

    How can I get customer support?

    Genius utilizes Crisp chat for customer support. You can access the chat widget in the lower left corner of the application.

    Genius: AI SaaS Study Guide

    Short Answer Questions (2-3 sentences each)

    1. What is a “full stack production ready software as a service platform”?
    2. Explain the concept of free and subscription tiers in a SaaS platform.
    3. How does the tutorial showcase the functionality of the music generation AI model?
    4. How is customer support integrated into the Genius platform?
    5. What advantage does ChatCNUI offer in terms of component creation?
    6. Explain the purpose and syntax of “route groups” in Next.js.
    7. What is the role of middleware.ts in the context of user authentication?
    8. Describe the integration of Clerk for user authentication in the project.
    9. How does the tutorial handle the display of the currently active page in the sidebar?
    10. What strategy is employed to limit the usage of free tier users?

    Short Answer Key:

    1. A “full stack production ready software as a service platform” is a comprehensive software solution delivered over the internet that includes all the necessary components (frontend, backend, database, etc.) to be deployed and used in a real-world environment.
    2. Free tiers offer limited access to the platform’s functionalities at no cost, attracting users and encouraging them to explore the service. Subscription tiers offer full access and advanced features for a recurring fee, generating revenue for the platform.
    3. The tutorial demonstrates music generation by prompting the AI to create a “piano solo,” resulting in a downloadable audio file. This showcases the model’s ability to generate original audio content.
    4. The tutorial integrates Crisp, a customer support platform, allowing users to report issues. These reports appear in real-time on the Crisp dashboard, enabling platform administrators to respond and assist users effectively.
    5. ChatCNUI simplifies component creation by generating well-structured, typed components. Users can easily customize these components while maintaining code quality and ownership over the component system.
    6. Route groups in Next.js are folders enclosed in parentheses that help organize routes without affecting the URL structure. This allows for better file management without impacting the user-facing URLs.
    7. middleware.ts is a file in Next.js that acts as an intermediary between the client and server, handling tasks like authentication. It checks if a user is logged in before allowing access to protected routes.
    8. Clerk is integrated as the authentication provider, offering pre-built UI components and secure authentication flows. It handles user registration, login, and session management, simplifying the implementation of user access control.
    9. The tutorial uses conditional styling based on the current pathname. If the pathname matches a specific route, the corresponding sidebar link is highlighted, indicating the currently active page to the user.
    10. The tutorial uses Prisma and a “user API limit” model to track the number of API calls made by free tier users. Once a user exceeds the defined limit, access to further API calls is restricted, prompting an upgrade to a paid tier.

    Essay Format Questions:

    1. Analyze the benefits and challenges of utilizing a pre-built component library like ChatCNUI in a large-scale SaaS project.
    2. Discuss the importance of authentication and authorization in a SaaS platform. Explain the role of middleware in enforcing these security measures.
    3. Evaluate the chosen approach for limiting free tier usage in Genius. Propose alternative methods and discuss their advantages and disadvantages.
    4. Critically analyze the integration of Stripe for subscription management in Genius. Discuss potential improvements and alternative payment gateway options.
    5. Explain the importance of customer support in a SaaS platform. Analyze the benefits and limitations of using a third-party solution like Crisp for customer communication.

    Glossary of Key Terms:

    • SaaS (Software as a Service): A software distribution model where applications are hosted by a provider and accessed by users over the internet.
    • Full Stack: Refers to the complete set of technologies required to build and run a software application, including frontend, backend, database, and infrastructure.
    • Production Ready: Software that is stable, reliable, and suitable for deployment in a live, real-world environment.
    • Free Tier: A pricing model where users get limited access to a service for free, often with restrictions on features or usage.
    • Subscription Tier: A pricing model where users pay a recurring fee for full access to a service, usually offering more features and higher usage limits.
    • Stripe: A payment processing platform that enables businesses to accept payments online.
    • Clerk: A user authentication and authorization service that provides pre-built UI components and secure authentication flows.
    • Next.js: A React framework for building web applications, offering features like server-side rendering, routing, and API routes.
    • Route Groups: Folders enclosed in parentheses in Next.js that allow for better route organization without affecting the URL structure.
    • middleware.ts: A file in Next.js that handles tasks like authentication by intercepting requests between the client and server.
    • Prisma: An ORM (Object Relational Mapper) that simplifies database interactions in Node.js applications.
    • PlanetScale: A serverless database platform that provides a scalable and managed MySQL database.
    • API Limit: A restriction on the number of API calls a user can make within a specific timeframe.
    • React Hot Toast: A library for displaying toast notifications in React applications.
    • Crisp: A customer support platform that offers chat, email, and knowledge base features.
    • Typewriter Effect: A library for creating a typing animation effect in React applications.
    • Lucid React: A library that provides a collection of SVG icons for use in React applications.
    • ChatCNUI: A tool for generating React components with predefined styles and functionality.
    • Zod: A TypeScript-first schema validation library that helps ensure data integrity.
    • Hook Form: A form management library for React that simplifies form validation and state management.
    • Replicate AI: A platform for running and sharing machine learning models, used for video and music generation in this project.
    • ZeroScope: A platform for monitoring and managing Replicate AI models.
    • Webhook: An automated notification sent from one application to another when a specific event occurs.
    • Hydration: The process of adding interactivity to server-rendered HTML by attaching JavaScript event handlers and state.

    This comprehensive study guide will help you review the key concepts and technical implementations detailed in the provided source material. By completing the activities and reviewing the glossary, you can gain a deeper understanding of the process involved in building a functional and engaging AI SaaS platform.

    Genius: An AI-Powered SaaS Platform

    I. Landing Page Components

    A. Landing Navbar (/components/LandingNavbar.tsx)

    This client-side React component renders the navigation bar specifically designed for the landing page. It conditionally displays links based on user authentication status, leading to the dashboard for logged-in users and sign-up for non-authenticated users. The navbar prominently features the platform’s logo and a “Get Started” button, encouraging immediate user engagement.

    B. Landing Hero (/components/LandingHero.tsx)

    The LandingHero component constitutes the main visual and textual element of the landing page. It showcases the platform’s core value proposition: “The best AI tools.” A dynamic Typewriter effect highlights key AI functionalities, captivating user attention. This client-side component also includes a call to action, leading users to the sign-up or dashboard based on their authentication status.

    II. Core Application Structure

    A. App Layout (/app/layout.tsx)

    This root layout component provides a consistent structure for the entire application. It includes essential providers for modals, toast notifications, and Crisp chat functionality, ensuring a seamless user experience.

    B. Dashboard Layout (/app/dashboard/layout.tsx)

    This layout component specifically structures the user dashboard. It utilizes server-side rendering to fetch the user’s API limit count and dynamically passes it as a prop to the sidebar component. This design leverages Next.js features for enhanced performance and data handling.

    III. AI Functionality and User Management

    A. Sidebar (/components/Sidebar.tsx)

    The Sidebar component provides navigation for the various AI tools offered by Genius. It displays a list of routes, each featuring an icon, label, and dynamically applied color based on the currently active page. The component integrates with user API limit data to display the user’s remaining free uses.

    B. Free Counter (/components/FreeCounter.tsx)

    This client-side component visually represents the user’s free usage quota within the sidebar. It utilizes the API limit count received as a prop to display the current usage against the maximum allowed free generations. The component features an “Upgrade” button, prompting users to subscribe to the pro plan upon exhausting their free quota.

    C. Subscription Button (/components/SubscriptionButton.tsx)

    The SubscriptionButton component dynamically renders different button actions depending on the user’s subscription status. It displays “Manage Subscription” for Pro users and “Upgrade” for free-tier users, seamlessly guiding users through the subscription management process.

    D. Pro Model (/components/ProModel.tsx)

    This client-side component acts as a modal, triggered when a free-tier user attempts to exceed their usage limits. It showcases the benefits of the Pro plan by listing all available AI tools, highlighting their value proposition. The modal includes a “Subscribe” button, directing users to the subscription checkout flow.

    E. API Limit Management (/lib/api-limit.ts)

    This module contains utilities for managing user API limits. It defines functions to increment user API usage counts whenever an AI tool is used and to check if a user has exceeded their free usage limits. The module integrates with Prisma to store and retrieve API usage data for each user.

    F. Subscription Management (/lib/subscription.ts)

    This module provides utilities for handling user subscriptions. It defines a function to check if a user has an active Pro subscription, taking into account subscription validity and expiration dates. The module integrates with Prisma to access user subscription data.

    G. Stripe Integration (/lib/stripe.ts)

    This module encapsulates the integration with the Stripe API for managing user subscriptions. It initializes the Stripe client and provides functionalities for creating and managing subscriptions, including interacting with Stripe webhooks for handling subscription events and updates.

    H. Stripe API Route (/app/api/stripe/route.ts)

    This server-side API route handles interactions with the Stripe API for creating and managing user subscriptions. It receives requests from the client-side subscription button component and interacts with the Stripe API to initiate checkout sessions and manage subscription updates based on webhook events.

    IV. Individual AI Tool Components

    A. Conversation Page (/app/dashboard/routes/conversation/page.tsx)

    This component implements the core user interface for the conversation AI tool. It includes a form for user input, utilizes the OpenAI API to generate responses, and displays the conversation history. The component integrates with the API limit management module to enforce free-tier usage limits and trigger the Pro Model modal when necessary.

    B. Code Generation Page (/app/dashboard/routes/code/page.tsx)

    C. Image Generation Page (/app/dashboard/routes/image/page.tsx)

    D. Music Generation Page (/app/dashboard/routes/music/page.tsx)

    E. Video Generation Page (/app/dashboard/routes/video/page.tsx)

    These components follow a similar structure to the Conversation Page, offering dedicated interfaces for each specific AI tool. Each component utilizes the corresponding API for generating outputs and integrates with the API limit management module for enforcing usage limits and promoting Pro subscriptions.

    This detailed table of contents provides an in-depth understanding of the code structure and functionality of the Genius platform, encompassing its landing page, core application structure, AI functionalities, and user management features. It facilitates navigation and understanding of the codebase for both developers and anyone interested in learning about the platform’s inner workings.

    Genius AI Platform Briefing Doc

    This briefing document reviews the main themes and functionalities of the Genius AI platform based on provided video transcripts.

    Core Functionality:

    Genius is a full-stack, production-ready SaaS platform offering a range of AI-powered tools, including:

    • Image Generation: Generates images based on user prompts (e.g., “a pretty sunset”).
    • Conversation Model: Provides conversational responses to user queries (e.g., “What is the radius of the Sun?”).
    • Music Generation: Creates audio files in various styles (e.g., “piano solo”).
    • Video Generation: Produces realistic videos based on detailed prompts (e.g., “clown fish swimming around a coral reef”).
    • Code Generation: Generates code snippets based on user instructions (e.g., “simple toggle button using React Hooks”).

    Technology Stack:

    • Next.js: Frontend framework for building dynamic web applications.
    • React: JavaScript library for building user interfaces.
    • Tailwind CSS: Utility-first CSS framework for styling.
    • Clerk: Authentication and user management service.
    • Stripe: Payment processing platform for subscription management.
    • Crisp: Customer support platform for real-time communication.
    • OpenAI: AI models for image, conversation, and code generation.
    • Replicate AI: AI models for video and music generation.
    • Prisma: Database toolkit for connecting to PlanetScale (MySQL).
    • PlanetScale: Serverless MySQL database.
    • Zod: Schema declaration and validation library for form inputs.
    • React Hook Form: Library for managing forms and form data.
    • React Markdown: Library for rendering Markdown content in React components.
    • Typewriter Effect: Library for creating a typewriter animation effect.

    User Experience:

    • Landing Page:Showcases the platform’s capabilities and encourages user signup.
    • Includes a dynamic hero section with a typewriter effect highlighting key features.
    • Offers a prominent “Start Generating for Free” call-to-action button.
    • Dashboard:Provides access to all AI tools via a visually appealing sidebar.
    • Displays a free usage counter, indicating remaining free generations.
    • Offers an “Upgrade to Genius Pro” button for unlocking unlimited usage.
    • AI Tools:Feature consistent UI elements, including heading components with icons, descriptions, and form fields.
    • Implement loading states and empty states for improved user feedback.
    • Leverage React Markdown for displaying structured responses (code snippets, formatted text).
    • Pro Model:A modal window that appears when free usage is exhausted.
    • Showcases the benefits of upgrading to the Pro plan.
    • Includes a visually distinct “Upgrade to Genius Pro” button with a gradient background.
    • Settings Page:Allows users to manage account settings and subscription details.
    • Displays the user’s current subscription status (Free or Pro).
    • Offers a “Manage Subscription” button for Pro users.
    • Error Handling:Uses React Hot Toast to display error messages to the user.
    • Provides informative messages in case of API errors or subscription issues.

    Key Features:

    • Free Tier: Allows users to explore the platform with limited free generations.
    • Monthly Subscription: Unlocks unlimited usage of all AI tools.
    • API Limits: Enforces usage limits for free tier users.
    • Stripe Integration: Manages subscription payments and user access levels.
    • Customer Support: Integrated Crisp chat for real-time customer assistance.

    Development Considerations:

    • Route Groups: Utilizes Next.js route groups to organize code without affecting URL structure.
    • Server Components: Leverages server components for database access and sensitive operations.
    • Client Components: Employs client components for UI interactions and state management.
    • Hydration Errors: Implements safeguards to prevent hydration errors caused by client-side logic in server components.
    • Code Reusability: Creates reusable UI components, such as buttons, cards, and headings.

    Quotes:

    • “This is not going to be your average AI tutorial. We are going to build a full-stack production-ready software as a service platform.”
    • “What would a software as a service be without customer support? In this tutorial, I’m also going to teach you how to build beautiful customer support using Crisp.”
    • “Genius is thinking…” (Loading state message)
    • “Understand, no conversation started.” (Empty state message for conversation model)
    • “Free trial has expired.” (Error message for exceeding free usage)

    Conclusion:

    Genius is a comprehensive AI platform offering a range of powerful tools and a user-friendly experience. The platform leverages a modern technology stack, implements robust error handling, and offers both free and paid subscription options. The integration of Clerk, Stripe, and Crisp ensures seamless authentication, payment processing, and customer support.

    Here is a summary of how the application in the sources utilizes both server and client components:

    • Server Components for Data Fetching and Authentication: The application leverages server components for critical tasks such as fetching data from the database using Prisma and handling authentication with Clerk. These operations are performed on the server side, ensuring data security and efficient handling of sensitive information. [1-6]
    • Client Components for Interactive UI Elements: Client components are employed for interactive elements within the user interface. Components like the sidebar, buttons, modals, and forms are rendered on the client side. This approach enhances user experience by enabling dynamic updates and interactions without requiring full page reloads. [7-15]
    • Server Components for API Routes: The application utilizes server components to define API routes that connect to external services like OpenAI and Replicate AI for AI functionalities. These routes handle requests from the client, interact with the AI APIs, and return the generated results back to the client. [16-20]
    • Client Components for Displaying AI Results: Client components are responsible for displaying the AI-generated results, such as conversation responses, code snippets, images, and music, to the user. They dynamically update the user interface based on the data received from the server-side API routes. [21-24]
    • Hydration and Server Component Refresh: The application employs techniques like router.refresh to rehydrate server components, ensuring that they fetch the latest data from the database after changes occur. This mechanism keeps the UI synchronized with the server-side state, providing a seamless experience for the user. [21, 25]

    The sources indicate that this architectural pattern, using both server and client components, offers several benefits, including improved security, enhanced user experience through dynamic interactions, and efficient data management.

    Here are the AI models implemented in the project discussed in the sources:

    • Image Generation: This model allows users to generate images based on text prompts. The user can specify the number of images and the resolution they desire. The model uses OpenAI’s DALL-E to generate the images. [1-3]
    • Video Generation: This model enables users to generate videos from text prompts. It utilizes the Zeroscope AI model from Replicate AI. [4, 5]
    • Conversation: This model functions as a conversational AI chatbot, allowing users to ask questions and receive responses. It employs the GPT-3.5-turbo model from OpenAI. [6-8]
    • Music Generation: Users can generate music based on text prompts with this model. It uses the “refusion” model from Replicate AI to create audio files. [6, 9]
    • Code Generation: This model allows users to generate code snippets using descriptive text prompts. It utilizes OpenAI and is designed to provide code in markdown format with comments for explanations. [8, 10-12]

    The sources indicate that the project aims to be a full-stack, production-ready SaaS platform with a free tier and a monthly subscription tier using Stripe. The tutorial teaches users how to build these AI tools and implement features like user authentication, API limits, customer support using Crisp, and a landing page. [1, 6, 13-16]

    The application uses Clerk for user authentication and Stripe for subscription management. Here’s a breakdown:

    Authentication

    • Users can sign in with their Google accounts or email addresses. [1]
    • Clerk handles the authentication process, providing sign-in and sign-up pages and managing user sessions. [2]
    • The application uses the app router from Next.js and has specific routes for sign-up and sign-in. [2]
    • Middleware is used to protect routes, redirecting unauthorized users to the sign-in page. [3]
    • The landing page is unprotected, allowing access to both logged-in and logged-out users. [3]
    • A User button component provided by Clerk is used on the dashboard, enabling users to sign out. [4]
    • The application controls the redirection URLs after sign-in and sign-out using environment variables. [3, 4]

    Subscription

    • The application offers a free tier with limited AI model usage (five times). [5, 6]
    • Prisma is used to store user API usage limits and subscription data. [7]
    • Each time a user utilizes an AI model, their usage count is incremented in the database. [8]
    • A checkAPIlimit function verifies if the user has exceeded their free usage limit. [9]
    • When a user exceeds their limit, a 403 error is returned, triggering a premium model prompt. [9, 10]
    • The premium model provides an option to upgrade to a Pro plan. [6, 11]
    • Clicking “Upgrade” initiates a Stripe checkout session. [12]
    • The checkout page uses the user’s email address from Clerk and pre-fills product details (Genius Pro, $20/month, unlimited generations). [13]
    • Stripe webhooks handle subscription events (checkout completion and invoice payment). [14]
    • Upon successful checkout, a webhook creates or updates the user subscription in the Prisma database, linking it to the user ID stored in the checkout session metadata. [15, 16]
    • A settings page allows users to manage their subscriptions, including viewing their status and accessing Stripe’s billing portal to cancel or modify their plans. [17]
    • Utilities like checkSubscription determine if a user has an active and valid Pro subscription, affecting UI elements and API access. [18, 19]

    This combination of Clerk and Stripe, along with Prisma for data management, allows for a robust authentication and subscription system that provides both free and paid access to the AI model functionalities.

    Building an AI SaaS Platform

    The sources provide a detailed walkthrough of building a full-stack AI SaaS platform. This discussion will highlight the key considerations and steps involved, drawing upon insights from the sources and prior conversations.

    1. AI Model Selection and Integration:

    • The first step is choosing the AI models that will power your SaaS. The sources focus on five key models: Image Generation (using OpenAI’s DALL-E), Video Generation (using Replicate AI’s Zeroscope), Conversation (using OpenAI’s GPT-3.5-turbo), Music Generation (using Replicate AI’s “refusion”), and Code Generation (using OpenAI). [1-36]
    • Integrating these models involves setting up accounts with the respective providers (OpenAI and Replicate AI) and obtaining API keys. [17, 31]
    • You’ll need to write API routes that handle user requests, interact with the AI model APIs, and return the generated results. [18, 19, 25, 30, 32, 35]

    2. Frontend Development:

    • The frontend should provide an intuitive user interface for interacting with the AI models. [13-16, 22, 27, 28, 33, 34, 37, 38]
    • The sources utilize Next.js with its app router, a React framework for building server-rendered applications. [5, 11]
    • The UI is built using Tailwind CSS for styling and a component library called chat cnui for pre-built UI elements like buttons, cards, and modals. [6-9, 13, 39]
    • Each AI model should have its dedicated page with an input area for user prompts, options for customization (like resolution or number of outputs), and a display area for the generated results. [14, 15, 24, 28, 33, 34]

    3. Authentication and Subscription Management:

    • To manage user access and monetize your SaaS, you need robust authentication and subscription systems. [12, 40, 41]
    • The sources employ Clerk for user authentication, allowing users to sign in using their Google accounts or email addresses. [12]
    • Stripe is used to handle payments and subscriptions, enabling both a free tier with limited usage and a paid Pro tier with unlimited access. [2, 3, 40]

    4. Database Integration:

    • A database is crucial for storing user data, usage limits, and subscription information. [36]
    • The sources choose PlanetScale, a serverless MySQL database platform, for data persistence. [42]
    • Prisma, an ORM (Object-Relational Mapper), is used to interact with the database, simplifying data modeling and querying. [36, 42]

    5. API Limits and Usage Tracking:

    • To enforce the free tier limitations, you’ll need to track user API usage. [36, 43]
    • The sources implement this by creating a “user API limits” table in the database and incrementing the count each time a user utilizes an AI model. [43]
    • A utility function checks if the user has exceeded their free usage limit before processing requests. [44]
    • If the limit is exceeded, the application triggers a premium model prompt, encouraging users to upgrade to the Pro plan. [45, 46]

    6. Customer Support Integration:

    • For user assistance and feedback collection, integrating a customer support solution is beneficial. [4]
    • The sources incorporate Crisp, a customer messaging platform, to provide live chat support. [47]

    7. Landing Page Design:

    • A compelling landing page is essential for attracting users and conveying the value proposition of your AI SaaS. [5]
    • The sources guide you through creating a visually appealing landing page that showcases the available AI models, highlights key features, and includes user testimonials. [38, 48]

    8. Deployment:

    • Finally, you’ll need to deploy your application to a production environment. [48]
    • The sources utilize Vercel, a platform optimized for Next.js applications, for deployment. [48, 49]
    • It’s important to configure environment variables correctly, including API keys, database connection strings, and webhook secrets, for a seamless production setup. [49-51]

    The sources offer a comprehensive roadmap for building a fully functional AI SaaS platform. By following the step-by-step instructions, you can gain valuable insights into the technical intricacies and design choices involved in creating a successful AI-powered business.

    OpenAI and Replicate AI in AI SaaS Development

    The sources primarily focus on building an AI SaaS platform and demonstrate the use of both OpenAI and Replicate AI for powering distinct AI models. This discussion will examine the roles of these two prominent AI providers within the context of the project.

    OpenAI

    OpenAI is a leading artificial intelligence research and deployment company. The sources showcase the use of three specific OpenAI models:

    • DALL-E for Image Generation: This model empowers users to create images from textual descriptions. The source code includes API calls to OpenAI’s image generation endpoint, sending user prompts and parameters like image count and resolution.
    • GPT-3.5-turbo for Conversational AI: This powerful language model serves as the foundation for the conversational chatbot feature. The code demonstrates setting up the model with an initial “system” message to define its role as a code generator, influencing its responses to align with this purpose.
    • Unspecified Model for Code Generation: The sources mention using OpenAI for code generation but don’t explicitly state which specific model is employed. The code highlights configuring the model to output code snippets in markdown format with code comments for explanations.

    The tutorial emphasizes obtaining an OpenAI API key, setting up environment variables, and handling API responses, including potential errors.

    Replicate AI

    Replicate AI is a platform that hosts and runs machine learning models. The sources use Replicate AI for two AI models:

    • Zeroscope for Video Generation: This model allows users to generate videos from text prompts. The code showcases integrating Zeroscope by invoking the replicate.run function, passing the model identifier and the user’s prompt as input. The source code also addresses the potential for long generation times with Replicate AI models and suggests utilizing webhooks for asynchronous processing to improve user experience.
    • “refusion” for Music Generation: This model enables users to create music from text descriptions. The code demonstrates integrating the “refusion” model using the Replicate AI API, similar to the Zeroscope implementation. The source code also acknowledges the potential for copyright issues with AI-generated music and advises caution when playing or sharing the outputs.

    The tutorial guides users through obtaining a Replicate AI API token, adding it to the environment variables, and handling API calls to generate video and music content.

    Key Observations and Insights

    • The sources demonstrate a strategic approach to model selection, leveraging both OpenAI and Replicate AI based on the specific capabilities of each provider for different AI tasks.
    • The source code provides practical examples of integrating and interacting with AI model APIs from both providers, including handling responses, potential errors, and asynchronous processing.
    • The sources highlight considerations like potential copyright concerns with AI-generated content, prompting developers to be mindful of ethical and legal implications.

    By utilizing both OpenAI and Replicate AI, the AI SaaS platform showcased in the sources gains access to a diverse range of AI capabilities, enhancing its functionality and appeal to users seeking various creative and practical applications.

    Subscription Model and API Limits

    The sources describe a freemium model for the AI SaaS platform. Users can access a free tier with limited usage, and a premium tier, called Genius Pro, is available for a monthly subscription fee. This approach allows users to try the platform’s capabilities before committing to a paid plan.

    Free Tier Limits

    The free tier restricts users to five AI model generations across all functionalities. This limit encourages users to experience the platform’s diverse capabilities while controlling resource usage.

    • A counter in the sidebar displays the remaining free generations to the user, providing transparency and a visual reminder of their usage. [1, 2]
    • The application employs Prisma to store user API limits in a database table called “user API limits”. Each time a user utilizes an AI model, their usage count is incremented. [3]
    • Utility functions checkAPIlimit and increaseAPIlimit are used to verify and update user usage counts. [4]

    When a user attempts to exceed their free limit, a 403 error is returned, prompting the premium model to open. [5]

    Premium (Genius Pro) Subscription

    The premium tier, Genius Pro, provides unlimited AI model generations for a monthly fee of $20. [6]

    • The premium model includes a button labeled “Upgrade” that directs users to a Stripe checkout page. [7]
    • The checkout page is pre-filled with the user’s email address from Clerk and includes product details for Genius Pro. [6]
    • Stripe webhooks handle subscription events, creating or updating user subscription data in Prisma upon successful checkout. [8]
    • A dedicated settings page allows users to manage their subscriptions, view their status, and access Stripe’s billing portal to cancel or modify their plan. [9]
    • Utility functions, such as checkSubscription, determine if a user has an active and valid Pro subscription. This information affects UI elements and access to AI models, unlocking unlimited usage for paid users. [10]

    Implementation Details

    • Stripe API: The platform integrates Stripe for handling payments and managing subscriptions. API keys and webhook secrets are stored in environment variables. [8, 11]
    • Prisma ORM: Prisma simplifies database interactions, allowing the application to efficiently store and manage user data, API limits, and subscription information. [12]
    • Next.js API Routes: Serverless functions handle API requests, interact with AI models from OpenAI and Replicate AI, and manage user authentication and subscription logic. [13]

    The combination of a freemium model, robust API limits, and seamless Stripe integration creates a sustainable and user-friendly monetization strategy for the AI SaaS platform. The sources provide a detailed roadmap for implementing this system, allowing developers to replicate and adapt the approach for their own AI-powered applications.

    Implementing Crisp Chat for Customer Support

    The sources demonstrate how to integrate Crisp, a customer messaging platform, into the AI SaaS platform to provide live chat support for users. This enables direct communication with users, facilitating assistance, feedback collection, and issue resolution.

    Crisp Integration Steps

    1. Crisp Account Creation: The first step involves setting up a free Crisp account. During setup, the sources advise using a dummy website URL as this can be updated later when deploying to a live production environment.
    2. Obtaining Website ID: Upon account creation, Crisp provides a unique website ID. This ID is crucial for configuring the Crisp SDK within the application.
    3. Installing the Crisp SDK: The Crisp SDK is installed using the command npm install crisp-sdk-web, adding the necessary library for interacting with Crisp’s chat functionality within the React application.
    4. Creating a Crisp Chat Component: A dedicated component, named crisp.chat.tsx, is created to house the Crisp integration logic. This component uses the useEffect hook to configure the Crisp SDK upon component mount. The crisp.configure method is called, passing the website ID obtained earlier.

    Crisp Provider and Layout Integration

    • To manage the Crisp chat component and ensure proper rendering, a CrispProvider component is created. This provider simply renders the CrispChat component, ensuring that the chat functionality is initialized and available throughout the application.
    • The CrispProvider is then integrated into the main layout file (layout.tsx) of the application. Placing it above the <body> tag ensures that the chat widget is loaded early in the rendering process.

    Key Benefits and Observations

    • Real-time Customer Support: Crisp provides a live chat interface, enabling users to instantly connect with the support team for assistance.
    • Seamless Integration: The Crisp SDK and React integration provide a smooth and straightforward setup process. The CrispChat and CrispProvider components encapsulate the integration logic, ensuring a clean and maintainable codebase.
    • Enhanced User Experience: By incorporating Crisp, the AI SaaS platform offers a readily accessible communication channel for users, fostering a more positive and supportive user experience.

    The integration of Crisp demonstrates a commitment to user satisfaction by providing a direct and responsive support channel. Users encountering issues or having questions can easily reach out for assistance, contributing to a more positive and engaging interaction with the AI SaaS platform.

    Landing Page Design and Deployment

    The sources provide a comprehensive walkthrough of building an AI SaaS application, including crafting an appealing landing page and deploying the project for public access.

    Landing Page Structure and Components

    The landing page is designed to attract potential users and showcase the platform’s capabilities. It consists of the following key components:

    • Landing Navbar: Situated at the top, the navbar features the Genius logo, links to the dashboard (for logged-in users) or sign-up page, and a “Get Started For Free” button with a premium style using a gradient background.
    • Landing Hero: This section occupies the most prominent space on the page, featuring a captivating headline “The Best AI Tools” enhanced by a typewriter effect that dynamically cycles through the platform’s key offerings: Chatbot, Photo Generation, Music Generation, Code Generation, and Video Generation. A concise description emphasizes the platform’s ability to expedite content creation using AI. A premium-styled button encourages users to “Start Generating For Free,” accompanied by a reassuring “No credit card required” message.
    • Landing Content: This section includes testimonials showcasing positive user experiences. The testimonials are presented in a responsive grid layout using cards with a dark background, white text, and no borders. Each card displays the user’s name, title, a brief description of their experience, and an avatar.
    • Footer: The sources don’t explicitly detail the footer content, but it’s common practice to include essential links, copyright information, and contact details in this section.

    Styling and Design Considerations

    The landing page employs a visually appealing and modern design:

    • Dark Background: The page utilizes a dark background color (#111827), creating a sophisticated and tech-focused aesthetic.
    • Gradient Accents: Gradient backgrounds are strategically used for premium buttons and text accents, adding visual interest and highlighting calls to action.
    • Responsive Layout: The landing page uses a responsive grid system to ensure optimal display across various screen sizes, adapting seamlessly to different devices.
    • Custom Font: The Montserrat font is imported from Google Fonts, lending a clean and modern typographic style to the page.
    • Typewriter Effect: The dynamic typewriter effect in the hero section adds dynamism and draws attention to the platform’s core AI features.

    Deployment Process

    The sources outline the deployment process using Vercel, a platform for deploying front-end applications:

    1. Post-Install Script: The package.json file is updated to include a postinstall script that runs prisma generate, ensuring Prisma client generation after installation.
    2. Code Linting: Running npm run lint checks for any code style errors or inconsistencies, promoting code quality and maintainability.
    3. GitHub Repository: The project is initialized as a Git repository and pushed to a new GitHub repository.
    4. Vercel Project Creation: A new project is created on Vercel, linking it to the GitHub repository containing the application’s code.
    5. Environment Variables: Environment variables, including API keys and secrets for OpenAI, Replicate AI, Stripe, and Clerk, are added to the Vercel project settings.
    6. Initial Deployment: The initial deployment is triggered. Note that the next public app URL environment variable will be set to localhost at this stage, requiring adjustments after the initial deployment succeeds.
    • Updating Environment Variables:The next public app URL variable is updated to the deployed application’s URL from Vercel.
    • The Stripe webhook URL is updated to point to the deployed application’s /api/webhook endpoint.
    • The Stripe webhook signing secret is retrieved from Stripe’s dashboard and added to the Vercel environment variables.
    1. Redeployment: The application is redeployed with the updated environment variables.
    2. Database Reset (Optional): For a clean deployment environment, the Prisma database can be reset using npx prisma migrate reset and then pushed to the PlanetScale database using npx prisma db push.

    The deployment process showcases best practices for deploying a modern web application, including utilizing version control, configuring environment variables, and leveraging a dedicated deployment platform like Vercel.

    Key Takeaways and Considerations

    • The landing page plays a crucial role in marketing the AI SaaS platform, providing a visually engaging and informative introduction to its capabilities.
    • The deployment process highlights the importance of setting up environment variables correctly, ensuring the application can access external services and APIs securely.
    • Developers deploying similar applications should adapt the environment variables and deployment steps to match their chosen hosting platforms and services.
    • The sources provide a solid foundation for understanding the process of designing an effective landing page and deploying a complex AI SaaS application.

    Redirection Logic for Login and Signup

    The sources provide a detailed explanation of how the code handles redirection after a user logs in or signs up using Clerk. The primary mechanism for this redirection is environment variables configured within the application and accessed by the Clerk library.

    Environment Variables for Redirection

    Within the application’s .env file (specifically dot.environment), four key environment variables dictate redirection behavior:

    • NEXT_PUBLIC_CLERK_SIGN_IN_URL: Specifies the URL for the sign-in page. The sources set this to /sign-in.
    • NEXT_PUBLIC_CLERK_SIGN_UP_URL: Specifies the URL for the sign-up page. The sources set this to /sign-up.
    • NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: Determines where a user is redirected after a successful login. The sources set this to /dashboard, ensuring users land on the protected dashboard area after logging in.
    • NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: Determines where a user is redirected after successfully creating an account. The sources set this to /dashboard as well, maintaining consistency in user experience after both sign-up and login actions.

    Clerk Integration and Redirection Handling

    The Clerk library utilizes these environment variables to manage the redirection flow. When a user successfully logs in or signs up, Clerk automatically redirects them to the URL specified in the corresponding “after sign-in” or “after sign-up” environment variables.

    Middleware for Public Routes

    The application employs a middleware file (middleware.ts) to control access to specific routes based on authentication status. The middleware allows defining public routes that can be accessed by both logged-in and logged-out users. The landing page (/) is designated as a public route, enabling unrestricted access.

    Manual Redirection

    In addition to Clerk’s automatic redirection, the code implements manual redirection in specific scenarios:

    • Sign-Out: When a user signs out, the after sign-out URL environment variable (set to /) redirects them back to the landing page.
    • Billing Portal: The Stripe integration includes a billing portal where users can manage their subscriptions. When a user clicks on the “Manage Subscription” button in their settings, the application sends a request to a Stripe API route (/api/stripe). If the user has an existing subscription, this route generates a billing portal session and returns a URL to redirect the user to Stripe’s billing portal.

    Key Points and Observations

    • Environment variables provide a centralized and configurable way to manage redirection logic for different authentication events.
    • The Clerk library seamlessly handles redirection based on these environment variables, simplifying the development process.
    • Middleware ensures that protected routes, such as the dashboard, can only be accessed by authenticated users.
    • Manual redirection is implemented for specific scenarios, like sign-out and accessing Stripe’s billing portal, to enhance user experience and control the flow of the application.

    The code’s redirection logic effectively guides users to the appropriate pages after authentication events, creating a smooth and intuitive navigation experience.

    Landing Page Composition: Structure and Elements

    The sources provide a comprehensive guide to building an AI SaaS application, encompassing the creation of an engaging landing page. The landing page aims to entice potential users and highlight the platform’s features through a strategic arrangement of components.

    Key Components

    The landing page comprises the following key elements:

    • Landing Navbar: Positioned at the top, this navbar showcases the Genius logo, along with links that dynamically adjust based on the user’s authentication status. For logged-in users, a link to the dashboard is provided, while for those not logged in, a link to the sign-up page is presented. Additionally, a “Get Started For Free” button is included, featuring a visually appealing premium style implemented using a gradient background. [1]
    • Landing Hero: Occupying a central position on the page, the Landing Hero section aims to capture attention and convey the essence of the platform. It features the bold headline “The Best AI Tools,” further enhanced by a dynamic typewriter effect that sequentially displays the platform’s main offerings: Chatbot, Photo Generation, Music Generation, Code Generation, and Video Generation. [2, 3] A concise descriptive statement emphasizes the platform’s ability to significantly speed up content creation through AI. A prominently displayed button, styled with a premium gradient, encourages users to “Start Generating For Free.” This call to action is accompanied by a reassuring message: “No credit card required,” aiming to reduce friction in user engagement. [3]
    • Landing Content: This section incorporates testimonials designed to showcase positive user experiences with the platform. These testimonials are structured within a responsive grid layout, utilizing cards with a dark background, white text, and no borders. Each card presents the user’s name, title, a succinct description of their experience, and an avatar. [4]
    • Footer: While the sources do not explicitly detail the footer’s content, it’s generally understood that this section would typically contain important links, copyright information, and ways to contact the platform. This understanding is based on common website conventions and is not explicitly mentioned in the provided sources.

    Visual Design and Styling

    The landing page exhibits a visually compelling and modern design through the implementation of various stylistic elements:

    • Dark Background: The page adopts a dark background color (#111827), contributing to a sophisticated and technology-oriented aesthetic. [5]
    • Gradient Accents: Gradient backgrounds are strategically applied to premium-styled buttons and text elements, adding visual depth and drawing attention to calls to action. [1, 3]
    • Responsive Layout: A responsive grid system is employed to ensure optimal display across diverse screen sizes, allowing the landing page to adapt seamlessly to various devices. [4]
    • Custom Font: The Montserrat font, imported from Google Fonts, provides a clean and contemporary typographic style to the landing page. [5]
    • Typewriter Effect: The dynamic typewriter effect within the Landing Hero section introduces a sense of activity and highlights the platform’s core AI features. [3]

    The structure and design of the landing page work cohesively to present a compelling introduction to the AI SaaS platform, emphasizing its key features, benefits, and ease of use.

    Pathways to Premium Features: Unlocking Full Potential

    The sources, which detail the development of an AI SaaS platform, outline a clear path for users to access and enjoy premium features. The model relies on a freemium approach, offering a limited free tier while providing a subscription option to unlock the full power of the platform.

    Freemium Model: A Taste of Genius

    The platform allows users to experience its capabilities through a free tier, granting them a limited number of AI generations. This strategy enables potential subscribers to try the platform’s features firsthand before committing to a paid plan. The sources set this limit to five generations across all AI functionalities (conversation, image generation, music generation, code generation, and video generation) [1-3]. This limit is tracked using Prisma, a database toolkit, to manage and persist user API limits [3, 4].

    Once a user exhausts their allocated free generations, they are prompted to upgrade to the premium plan to continue using the platform [2]. The application elegantly handles this transition by displaying a “Pro Model” prompt, which outlines the benefits of subscribing and provides a clear call to action to upgrade [2, 5].

    Subscription: Embracing Unlimited AI Power

    The sources primarily focus on outlining the technical implementation of the subscription system, using Stripe as the payment gateway [2, 6]. The platform offers a “Genius Pro” subscription plan, priced at $20 per month, which grants users unlimited access to all AI generation capabilities [7].

    While the sources emphasize the technical aspects, they do not explicitly discuss the specific benefits and added features available exclusively to premium subscribers. However, the primary advantage of the subscription plan, heavily implied in the sources and our previous conversation, is the removal of usage limitations imposed by the free tier [2, 7]. This unlimited access empowers users to fully leverage the platform’s capabilities, enabling them to generate content without restrictions.

    Key Takeaways: Accessing Premium Features

    • Limited Free Tier: Users can experiment with the platform’s AI functionalities with a limited number of free generations [1-3].
    • Subscription Model: The “Genius Pro” subscription, priced at $20 per month, unlocks unlimited access to all AI generation features, removing the limitations of the free tier [7].
    • Clear Upgrade Path: When users reach their free usage limit, they are presented with a “Pro Model” prompt, guiding them towards the premium subscription [2, 5].

    The sources predominantly focus on the technical implementation of the freemium and subscription models. While they clearly establish the path for users to access premium features, they do not explicitly detail any exclusive features or functionalities reserved for paying subscribers beyond the removal of usage limits.

    Benefits of PlanetScale for Application Development

    The sources, which provide a detailed walkthrough of building an AI SaaS application, showcase the use of PlanetScale as the database provider. PlanetScale’s unique features and capabilities offer several advantages during application development.

    MySQL Compatibility and Scalability

    PlanetScale leverages the familiar and widely adopted MySQL relational database management system. This compatibility simplifies the development process, as developers can leverage their existing MySQL knowledge and readily integrate the database into the application. [1]

    Moreover, PlanetScale offers seamless scalability, a critical factor for SaaS applications aiming for growth. The platform’s ability to handle increasing data volumes and user traffic ensures a smooth and responsive user experience, even as the application scales to accommodate a larger user base.

    Branching and Non-Blocking Schema Changes

    One of PlanetScale’s standout features, highlighted in our conversation history, is its branching capability, akin to version control systems like Git. [1] This functionality allows developers to create branches for schema modifications, enabling testing and validation of changes in isolated environments without impacting the live production database. This feature significantly reduces risks associated with database migrations and promotes a more agile development workflow.

    Furthermore, PlanetScale supports non-blocking schema changes. [1] This means developers can apply modifications to the database schema without causing downtime or disruptions to the application’s operation. This capability is particularly valuable in SaaS environments, where continuous uptime is crucial for user satisfaction and business continuity.

    Serverless Architecture and Simplified Management

    PlanetScale operates as a serverless database platform, abstracting away the complexities of infrastructure management. [1] This frees developers from the burdens of server provisioning, maintenance, and scaling, allowing them to focus on building and enhancing the application’s core features.

    Integration with Prisma: Seamless Database Interaction

    The application leverages Prisma, a database toolkit, to interact with PlanetScale. [1] Prisma provides a powerful and type-safe ORM (Object-Relational Mapping) layer, simplifying database operations within the application’s code. The combination of PlanetScale’s MySQL compatibility and Prisma’s ease of use streamlines database interaction and enhances developer productivity.

    Benefits Recap:

    • MySQL Compatibility: Facilitates easy integration and leverages developers’ existing MySQL expertise.
    • Scalability: Handles increasing data volumes and user traffic, ensuring optimal performance as the application grows.
    • Branching and Non-Blocking Schema Changes: Promotes safe and agile database schema management without downtime.
    • Serverless Architecture: Simplifies database management by abstracting away infrastructure complexities.
    • Integration with Prisma: Provides a type-safe and user-friendly ORM layer for streamlined database interaction.

    The use of PlanetScale as the database provider offers several advantages for developing the AI SaaS application. Its compatibility, scalability, ease of management, and integration with Prisma contribute to a smooth, efficient, and robust development process.

    The Role of router.refresh() in Updating Server Components

    The sources describe the implementation of an AI SaaS platform using Next.js 13. The application leverages server components for various functionalities, including fetching and displaying the user’s remaining free generations. The use of router.refresh() plays a crucial role in ensuring that server components are rehydrated with the latest data from the database.

    Triggering Server Component Rehydration

    When a user submits a prompt to one of the AI models, the application makes an API request to the corresponding server component to generate the output. After the response is received and processed, the router.refresh() function is called within a finally block. This function, part of the useRouter hook from next/navigation, forces all server components to re-fetch data and update their state.

    Maintaining Accurate Free Generation Count

    In the context of the AI SaaS application, router.refresh() is instrumental in keeping the displayed free generation count accurate. The application uses a server component within the layout.tsx file to fetch and display this count using the getAPIlimitCount() utility function. This function retrieves the count from the PlanetScale database using Prisma.

    Without router.refresh(), the server component responsible for displaying the free generation count would not automatically update after a user consumes a generation. This would result in a stale display, showing an incorrect number of remaining generations. By calling router.refresh() after each API request to an AI model, the application ensures that all server components, including the one responsible for the free generation count, are updated with the latest data from the database.

    Key Benefits of router.refresh()

    • Real-time Data Updates: Ensures that server components reflect the most current data from the database.
    • Simplified State Management: Eliminates the need for manual state updates or complex synchronization mechanisms.
    • Improved User Experience: Provides users with an accurate and up-to-date view of their usage and subscription status.

    The strategic use of router.refresh() in the AI SaaS application simplifies state management and ensures that server components always display the most up-to-date information. This approach contributes to a seamless and responsive user experience, accurately reflecting the user’s remaining free generations and subscription status.

    Platform’s Authentication Mechanism: A Closer Look at Clerk

    The sources outline the development of an AI SaaS application, emphasizing the technical implementation of user authentication using Clerk, a third-party authentication provider.

    Clerk Integration for Simplified Authentication

    The application seamlessly integrates Clerk to handle user authentication, simplifying the often complex process of managing user accounts, passwords, and security measures. Clerk’s integration within the Next.js 13 application follows a structured approach, as detailed in the sources.

    Steps for Clerk Integration:

    • Installation: The clerk/nextjs package is installed using npm, bringing in the necessary components and utilities.
    • Configuration: Environment variables, including the Clerk publishable key and secret key, are set in the .env file. Additional environment variables, such as sign-in and sign-up URLs, and redirect URLs after successful authentication actions, are also configured to customize the authentication flow.
    • Provider Setup: The application wraps its root layout component (layout.tsx) with the ClerkProvider component. This sets up the necessary context for Clerk to manage authentication throughout the application.
    • Middleware Implementation: A middleware file (middleware.ts) is created to define authentication rules and handle redirects. It includes logic to protect specific routes, requiring users to be authenticated before accessing them. The middleware also defines public routes that do not require authentication, ensuring that unauthenticated users can access certain sections of the application, such as the landing page.
    • Sign-in and Sign-up Pages: The application creates dedicated sign-in and sign-up pages using Clerk’s pre-built UI components. These components offer a customizable and user-friendly interface for users to register and authenticate with the platform.
    • User Button: The application utilizes the UserButton component provided by Clerk to display the currently logged-in user’s information. This component allows users to manage their profile and sign out of the application.

    Clerk’s Role in Authentication

    Clerk handles the heavy lifting of user authentication, providing secure mechanisms for user registration, login, password management, and session management. The application leverages Clerk’s pre-built UI components and API to streamline the authentication process, reducing the amount of custom code required.

    By delegating authentication to Clerk, the application benefits from:

    • Simplified Development: Reduces the complexity of building and maintaining authentication logic.
    • Enhanced Security: Leverages Clerk’s robust security measures and best practices.
    • Improved User Experience: Provides users with a seamless and familiar authentication experience.

    Authentication and API Access Control

    The sources also highlight how user authentication, managed by Clerk, plays a crucial role in controlling access to the platform’s API endpoints.

    Unauthorized Access Prevention:

    In the API routes responsible for the various AI models, the auth() function from clerk/nextjs is used to retrieve the user ID of the currently authenticated user. If no user ID is present, indicating an unauthenticated user, the API route returns an “unauthorized” response (401 status code), preventing access to the functionality.

    Premium Feature Access Control:

    The application implements a freemium model, allowing users to access premium features, such as unlimited AI generations, through a paid subscription. The checkAPIlimit() utility function, which relies on the user ID retrieved from auth(), determines whether the user is authorized to access the requested functionality based on their subscription status.

    Key Takeaways

    • Clerk Integration: The application seamlessly integrates Clerk, a third-party authentication provider, to manage user authentication.
    • Simplified Authentication: Clerk’s pre-built UI components and API streamline the authentication process, reducing development complexity.
    • Secure and User-friendly: Clerk enhances security and provides a familiar authentication experience for users.
    • API Access Control: User authentication, managed by Clerk, is used to control access to API endpoints, ensuring that only authorized users can access specific functionalities.

    The sources provide a comprehensive overview of how the AI SaaS platform handles user authentication using Clerk. By leveraging Clerk’s capabilities, the application simplifies authentication management, enhances security, and controls access to premium features based on user subscription status.

    Benefits of the Vercel AI SDK: Expanding on the Potential

    While the sources provide a detailed walkthrough of building an AI SaaS application using Next.js 13 and various AI providers like OpenAI and Replicate, they don’t directly mention or utilize the Vercel AI SDK. However, based on the application’s structure and challenges encountered, it’s possible to explore how incorporating the Vercel AI SDK could potentially enhance the platform.

    Addressing API Route Timeout Issues with Edge Functions

    The sources mention that deploying the application on Vercel’s free “Hobby” plan might lead to timeout issues for AI models with longer generation times, such as music or video generation. This limitation arises from the serverless function execution time constraints on the Hobby plan.

    The Vercel AI SDK, designed for deploying and managing AI models on Vercel’s edge network, could provide a solution to these timeout challenges. By leveraging edge functions, which execute closer to users and offer increased execution time limits, the application could accommodate AI models with longer processing times without requiring an upgrade to a higher-tier Vercel plan. This approach would improve the reliability and responsiveness of the platform, ensuring a smoother user experience, especially for resource-intensive AI models.

    Streamlining AI Model Deployment and Management

    The sources demonstrate the process of integrating and interacting with different AI providers, including OpenAI and Replicate. While the integration steps are well-explained, managing multiple providers and their specific APIs could introduce complexity to the application’s codebase.

    The Vercel AI SDK aims to simplify AI model deployment and management on the Vercel platform. It provides a unified interface for interacting with various AI providers, potentially streamlining the integration process and reducing code complexity. This could lead to a more maintainable and scalable codebase, facilitating easier adoption of new AI models and providers in the future.

    Potential for Enhanced Performance and Scalability

    The Vercel AI SDK leverages the power of Vercel’s edge network, known for its low latency and global distribution. Deploying AI models through the SDK could potentially lead to improved performance and scalability for the AI SaaS application.

    By executing AI models closer to users on the edge, the application could reduce response times and enhance the overall user experience. Additionally, the scalability of the edge network ensures that the platform can handle increased traffic and demand as the user base grows.

    Important Considerations

    • The information regarding the Vercel AI SDK and its potential benefits is not explicitly derived from the sources. It is based on general knowledge of the SDK and its capabilities.
    • Further research and testing would be necessary to validate the specific advantages of using the Vercel AI SDK within the context of this particular AI SaaS application.

    While the sources do not explicitly mention the Vercel AI SDK, its features, particularly the use of edge functions and a unified interface for AI providers, could potentially address the challenges of API timeout limitations and streamline the management of multiple AI providers. Further exploration and testing would be needed to confirm the specific benefits within the application’s context.

    Handling Subscription Payments: The Stripe API in Action

    The sources provide a detailed walkthrough of integrating the Stripe API into an AI SaaS application to manage user subscriptions and payments. They outline the steps involved in setting up Stripe, creating checkout sessions, handling webhooks, and managing user subscriptions within the application.

    Stripe Account Setup and API Key Configuration

    • Account Creation: The first step involves creating a Stripe account and navigating to the developer dashboard to obtain the necessary API keys.
    • Secret Key Storage: The Stripe secret key, crucial for secure API communication, is stored in the application’s environment variables (.env file).
    • Stripe Client Initialization: A Stripe client is initialized within a utility file (stripe.ts) using the secret key. This client is used to interact with the Stripe API throughout the application.

    Creating a Subscription Checkout Flow

    • Stripe Route: A dedicated API route (/api/stripe) is created to handle subscription requests. This route utilizes the Stripe client to manage checkout sessions and billing portal interactions.
    • Authentication Check: Upon receiving a request, the route first verifies if the user is authenticated using Clerk. If not, it returns an unauthorized response.
    • Existing Subscription Check: If the user is authenticated, the route checks if they already have an active subscription.
    • Billing Portal Redirection: If an active subscription exists, the route uses the billing_portal.sessions.create() method from the Stripe API to generate a billing portal session and redirects the user to it. This allows users to manage their existing subscriptions, including upgrades, cancellations, and payment method updates.
    • Checkout Session Creation: If no active subscription is found, the route utilizes the checkout.sessions.create() method to generate a new checkout session. This session includes details about the subscription plan, such as pricing, billing interval, and product information.
    • Essential Metadata: Critically, the checkout session includes the user’s ID as metadata. This metadata is crucial for linking the checkout session with the corresponding user in the application’s database, ensuring that the subscription is correctly assigned.
    • Checkout URL Return: In both cases (billing portal or checkout session), the route returns a JSON response containing the URL for the generated session. This URL is used on the client-side to redirect the user to the appropriate Stripe interface.

    Handling Webhooks for Subscription Events

    Stripe webhooks play a crucial role in notifying the application about events related to user subscriptions, such as successful payments, subscription updates, and cancellations.

    • Webhook Route Creation: The application sets up a dedicated API route (/api/webhook) to handle incoming webhook events from Stripe.
    • Webhook Secret Configuration: A webhook signing secret, obtained from the Stripe dashboard, is securely stored in the application’s environment variables. This secret is used to verify the authenticity of incoming webhooks, ensuring they are indeed from Stripe.
    • Event Handling: The webhook route uses the stripe.webhooks.constructEvent() function to verify the signature of the incoming webhook and parse the event data. The route then handles different event types:
    • checkout.session.completed: This event is triggered when a user successfully completes a checkout session and subscribes to a plan. The route retrieves the subscription details from Stripe, creates a new user subscription record in the application’s database, and links it to the user using the metadata included in the checkout session.
    • invoice.payment_succeeded: This event is triggered when an invoice payment for a subscription is successful, often indicating a renewal. The route updates the existing user subscription in the database, reflecting the new billing period and potentially any changes in the subscription plan.
    • Response and Security: The webhook route returns a 200 OK response to Stripe, acknowledging successful event processing. The route is secured using Clerk middleware, ensuring that only authenticated requests from Stripe are processed.

    Managing User Subscriptions Within the Application

    • Subscription Status Check: The application utilizes a utility function (checkSubscription()) to check the current subscription status of a user. This function retrieves subscription data from the database using the user ID and validates whether the subscription is active and within the current billing period.
    • Subscription Button Logic: A dedicated component (SubscriptionButton) handles the user interface for managing subscriptions. Depending on the user’s current subscription status, the button either displays “Manage Subscription” (for active subscribers) or “Upgrade” (for free users). Clicking the button triggers an API call to the /api/stripe route, which, as explained earlier, either redirects the user to the billing portal or initiates a new checkout session.
    • Freemium Model Enforcement: The application implements a freemium model, granting free users a limited number of AI generations. API routes for various AI models use the checkAPIlimit() function to determine if a user has exceeded their free limit. If so, they are presented with the ProModel, encouraging them to upgrade.
    • API Limit Management: The application tracks the number of API calls made by free users using the increaseAPIlimit() utility function, which updates a user’s usage count in the database.

    Key Concepts and Insights

    • Seamless Integration: The Stripe API integration within the AI SaaS application is thorough, encompassing account setup, checkout flows, webhook handling, and subscription management.
    • Security Considerations: The application emphasizes security by storing sensitive API keys in environment variables and verifying the authenticity of incoming Stripe webhooks.
    • Freemium Model and API Limits: The sources clearly demonstrate how to implement and enforce a freemium model, using Stripe for premium subscriptions and API limits to control free usage.
    • Importance of Metadata: The use of metadata in checkout sessions is crucial for linking Stripe events with corresponding users within the application.

    The sources provide a comprehensive overview of how the Stripe API is leveraged to handle subscription payments and manage user subscriptions within the AI SaaS platform. The integration demonstrates key concepts in payment processing, webhook management, subscription lifecycle management, and secure API communication.

    Free Trial Exhausted: Encouraging the Upgrade

    The application implements a freemium model, allowing free users a limited number of AI generations before prompting them to upgrade to a paid subscription. Here’s a breakdown of what happens when a free user exceeds their limit:

    • API Limit Check: The API routes for each AI feature (conversation, code generation, image generation, music generation, video generation) utilize the checkAPIlimit() function. This function queries the application’s database to determine if the user has surpassed their allotted free generations. [1]
    • 403 Forbidden Response: If the free limit is exceeded, the API route returns a NextResponse with a 403 Forbidden status code. This status code signifies that the user is not authorized to access the requested resource (the AI generation). [2]
    • Client-Side Error Handling: The front-end application intercepts this 403 error within the onSubmit function of each AI component. [3, 4]
    • Pro Model Trigger: Upon detecting the 403 error, the client-side code triggers the ProModel component, which presents a modal window to the user. [3, 4]
    • Upgrade Prompt: The ProModel displays information about the benefits of upgrading to a paid “Genius Pro” subscription, emphasizing the removal of generation limits. [3]
    • Subscription Button: The modal includes a prominent “Upgrade” button, styled distinctively to encourage user action. [5]
    • Stripe Integration: Clicking the “Upgrade” button initiates the Stripe checkout flow, as detailed in a previous response, guiding the user through the subscription purchase process. [6]

    In essence, when a free user exhausts their allotted generations, the application gracefully handles the situation by:

    1. Blocking further free access to the AI features.
    2. Presenting a clear upgrade prompt, highlighting the advantages of a paid subscription.
    3. Seamlessly integrating with Stripe, facilitating a smooth subscription purchase experience.

    This approach effectively encourages free users to convert to paying subscribers while maintaining a positive user experience.

    Navigating the Free Tiers: OpenAI and Replicate AI

    While the sources primarily focus on building an AI SaaS application and integrating Stripe for subscriptions, they do offer some insights into the free tiers provided by OpenAI and Replicate AI.

    OpenAI’s Free Trial

    The sources mention that OpenAI offers a free trial for new users. [1] This trial provides a specific amount of credit, potentially $5, that users can utilize within the first three months of account creation. [1] However, the exact details of OpenAI’s current free tier offerings are not explicitly stated in the sources. The information provided pertains to the speaker’s experience during the tutorial’s development. To obtain the most up-to-date information on OpenAI’s free tier, it is recommended to consult their official website or documentation.

    Replicate AI’s Free Tier

    The sources highlight that Replicate AI also offers a free tier for users. [2] Unlike OpenAI, the specific details of Replicate AI’s free tier are not explicitly outlined in the sources. It is suggested that users exercise caution and avoid excessive API requests to stay within the free usage limits. [2] Similar to OpenAI, to get the most accurate and current information on Replicate AI’s free tier, it would be best to refer to their official website or documentation.

    Insights from the Sources

    • Emphasis on Cost-Effectiveness: The sources emphasize that both OpenAI and Replicate AI offer free tiers, enabling developers to build and experiment with AI applications without incurring immediate costs.
    • Limited Information on Specifics: The sources provide limited information about the exact features, usage limits, and credit allocations within the free tiers of both platforms. It is implied that these details may vary and are subject to change.
    • Recommendation for Independent Verification: The sources suggest that users refer to the official documentation or websites of OpenAI and Replicate AI to obtain the most up-to-date and accurate information on their free tier offerings.

    The sources provide an overview of the existence of free tiers for both OpenAI and Replicate AI but lack specific details about their current offerings. For comprehensive information, it is advisable to consult the official resources of both platforms.

    Vercel Hobby Plan Limitations: Insights from the Sources

    While the sources primarily focus on building an AI SaaS application and integrating various services like Stripe, OpenAI, and Replicate AI, they touch upon the limitations of deploying such an application on Vercel’s Hobby plan, specifically concerning API route timeouts.

    API Timeout Challenges on the Hobby Plan

    The sources highlight that deploying the developed AI SaaS application on Vercel’s free Hobby plan can lead to challenges, particularly with AI models that require extensive processing time. The speaker notes that certain actions, such as music or video generation, may take a significant amount of time, potentially exceeding the timeout limits imposed by the Hobby plan.

    • Exceeding Timeout Limits: The sources explain that if an API route takes too long to process a request (e.g., generating a complex music piece or video), it might hit the timeout limit enforced by the Hobby plan, resulting in errors. This is especially relevant for AI models that inherently involve substantial computation and processing time.
    • Impact on User Experience: API timeouts can negatively impact the user experience. If a user initiates a request for a computationally intensive AI generation and encounters a timeout error, it can lead to frustration and a perception of unreliability.

    Potential Solutions and Alternatives

    The sources suggest a few potential solutions or alternatives to mitigate the limitations of using the Vercel Hobby plan for this type of AI application:

    • Upgrading to a Higher Plan: Vercel offers paid plans with more generous resource allocations, including longer API route timeout limits. Upgrading to a paid plan could provide the necessary headroom to accommodate the processing time required for complex AI models.
    • Exploring Vercel AI SDK: The speaker mentions the Vercel AI SDK as a potential alternative. While not explicitly covered in the provided sources, the speaker indicates that this SDK, designed for AI applications, offers advantages such as longer timeouts, faster processing through edge network utilization, and support for content streaming.

    Key Points and Observations

    • Hobby Plan Suitability: The sources imply that Vercel’s Hobby plan, while suitable for many applications, might not be the ideal choice for production-level AI SaaS platforms that involve computationally intensive models with longer processing times.
    • Timeout Constraints: The limited API timeout on the Hobby plan can lead to errors and disruptions for users if AI generation requests exceed the allowed processing duration.
    • Mitigation Strategies: The sources briefly touch upon potential solutions, such as upgrading to a paid Vercel plan or exploring the capabilities of the Vercel AI SDK, which is designed to handle the demands of AI workloads more effectively.

    The sources provide a glimpse into the limitations of using Vercel’s Hobby plan for production-level AI applications, specifically highlighting the potential for API timeouts when dealing with resource-intensive AI models. The information, however, is presented in a conversational context and primarily focuses on guiding users through the tutorial, rather than providing an exhaustive analysis of Vercel’s pricing plans or alternatives. For a more in-depth understanding of Vercel’s offerings and the best deployment options for your specific application, it is recommended to consult Vercel’s official documentation and explore their various plans and features.

    metadata: Connecting Stripe Checkouts with Users

    The metadata object plays a crucial role in linking a successful Stripe checkout session back to the specific user who made the purchase in the application. The sources emphasize that this is essential for managing user subscriptions effectively.

    The Challenge: Anonymous Checkouts

    When a user initiates a Stripe checkout, the process occurs independently of the main application. Stripe handles the payment flow, and the application only receives notifications about the outcome (success or failure). The challenge is that, by default, the checkout process doesn’t provide a direct link between the payment and the user’s account in the application.

    metadata: Bridging the Gap

    The metadata object within the Stripe checkout session serves as this crucial bridge. It allows developers to embed custom information into the checkout session. In the context of the AI SaaS application, the critical piece of information passed within metadata is the user ID.

    How metadata Works:

    1. Checkout Session Creation: When creating a Stripe checkout session using stripe.checkout.sessions.create(), the application includes the logged-in user’s ID within the metadata object.
    2. metadata: {
    3. userId: user.id,
    4. }
    5. Webhook Event: Upon a successful checkout (signaled by the checkout.session.completed event), Stripe sends a webhook notification to the application’s designated webhook endpoint.
    6. User Identification: The webhook handler, using the Stripe API, retrieves the completed checkout session details. Crucially, it accesses the metadata object within the session to extract the stored userId.
    7. Subscription Creation/Update: Armed with the userId, the application can now:
    • Create a new subscription record in its database, associating the Stripe subscription details with the correct user.
    • Update an existing subscription record if the user is renewing or modifying their plan.

    Importance of metadata:

    • Accurate Subscription Management: Without the user ID in metadata, the application wouldn’t know which user to grant the subscription to, leading to discrepancies and potential revenue loss.
    • Personalized User Experience: Knowing the subscribed user allows the application to unlock premium features, display personalized billing information, and tailor the user experience accordingly.

    The metadata object is a subtle but powerful tool within Stripe’s checkout flow. It ensures that successful checkouts are correctly linked to the corresponding users in the application, enabling robust subscription management and a seamless user experience.

    Installing Prisma as a Development Dependency

    Running the command npm install -D prisma installs Prisma as a development dependency in your project. Let’s break down this command and understand its purpose within the context of building the AI SaaS application described in the sources.

    Understanding the Command:

    • npm: This is the Node Package Manager, a command-line tool used to manage packages (libraries, frameworks, tools) in Node.js projects.
    • install: This subcommand instructs npm to install a specific package.
    • -D: This flag, short for –save-dev, indicates that the package should be installed as a development dependency.
    • prisma: This is the name of the package we want to install—the Prisma ORM (Object-Relational Mapper).

    Development Dependencies vs. Regular Dependencies:

    In Node.js projects, dependencies are categorized into two types:

    • Regular Dependencies: These are packages that are essential for the application to run in production. They are included in the final production build.
    • Development Dependencies: These are packages that are used during development but are not needed for the application to function in a production environment. Examples include testing frameworks, code linters, and build tools.

    Why Prisma is a Development Dependency:

    Prisma, while crucial for database interactions during development, is typically not required in the production runtime environment.

    • Database Schema Management: Prisma is primarily used to define and manage the database schema, generate type-safe database clients, and interact with the database during development. These tasks are typically performed during the development and build phases.
    • Production Deployment: In production, the database schema is often considered static, and the application interacts with the database through the generated Prisma client, which can be included in the production build.
    • Optimization: Installing Prisma as a development dependency helps keep the production build leaner, as it excludes unnecessary packages that are not directly involved in the runtime execution of the application.

    Prisma’s Role in the AI SaaS Application:

    In the sources, Prisma is used to:

    • Define the Database Schema: The schema.prisma file defines the data models for user API limits (user_api_limit) and user subscriptions (user_subscription).
    • Generate a Type-Safe Client: The command npx Prisma generate generates a type-safe Prisma client, which provides functions to interact with the database in a way that is checked by TypeScript.
    • Manage Database Migrations: The command npx Prisma db push pushes changes in the data model to the database, effectively managing database migrations.
    • Query and Update Data: The application code uses the generated Prisma client to query and update data in the database (e.g., checking API limits, storing subscription details).

    Key Points:

    • npm install -D prisma installs Prisma as a development dependency, meaning it is used during development but is not included in the production build.
    • Development dependencies are useful for tools and libraries needed during development, but not for the runtime execution of the application.
    • Prisma, as an ORM, is mainly used for schema management, client generation, and database interactions during development.
    • The generated Prisma client is included in the production build, allowing the application to communicate with the database in a type-safe manner.

    By understanding the concept of development dependencies and Prisma’s role in the application, you can see why npm install -D prisma is a logical choice for this project.

    Implementing the “Pro Model” Loading State

    The sources describe the implementation of a “Pro Model” component that appears when a user has exceeded their free API usage limits or clicks on an “Upgrade” button. Here’s how a loading state is integrated into this component:

    1. Initializing the Loading State

    Within the ProModel component, a loading state is initialized using React’s useState hook:

    const [loading, setLoading] = useState(false);

    This creates a state variable loading with an initial value of false, indicating that the model is not in a loading state by default. The setLoading function allows you to update the loading state.

    2. Triggering the Loading State

    The loading state is triggered in the onSubscribe function, which is executed when the user clicks the “Upgrade” button within the “Pro Model”. Here’s the relevant code:

    const onSubscribe = async () => {

    try {

    setLoading(true); // Activate loading state

    // … Axios request to initiate Stripe checkout

    } catch (error) {

    // … Error handling

    } finally {

    setLoading(false); // Deactivate loading state

    }

    };

    When the “Upgrade” button is clicked:

    • setLoading(true) is called to set the loading state to true, indicating that an operation is in progress.
    • An Axios GET request is sent to the /api/stripe endpoint to initiate the Stripe checkout process.
    • In the finally block, setLoading(false) is called to deactivate the loading state, regardless of whether the checkout request was successful or resulted in an error.

    3. Using the Loading State in the Button

    The loading state variable is used to control the disabled state of the “Upgrade” button:

    <Button

    // … other props

    disabled={loading}

    onClick={onSubscribe}

    >

    Upgrade

    </Button>

    • When loading is true, the button becomes disabled, preventing the user from clicking it again while the checkout process is ongoing.
    • When loading is false, the button is enabled, allowing the user to initiate the checkout flow.

    Enhancements: Visual Feedback (Not in Sources)

    The sources primarily focus on the functional aspect of disabling the button during the loading state. To provide a better user experience, you could enhance the loading state implementation by adding visual feedback. Here are a few ideas that are not explicitly covered in the sources and would require additional code and potentially external libraries:

    • Spinner: Display a loading spinner or animation within the button while loading is true.
    • Text Change: Change the button text to “Upgrading…” or a similar message to indicate the action in progress.
    • Overlay: Add a semi-transparent overlay over the entire “Pro Model” content to visually emphasize that an operation is ongoing.

    Key Points

    • The loading state prevents multiple clicks on the “Upgrade” button while the Stripe checkout is in progress.
    • The useState hook is used to manage the loading state variable.
    • The disabled prop of the Button component is controlled by the loading state.
    • Consider adding visual feedback elements to enhance the user experience during the loading state.

    By implementing a loading state, the application provides a more responsive and user-friendly experience, clearly indicating that an operation is underway and preventing unintended duplicate actions.

    Integrating the “Pro Model” with Stripe for Subscriptions

    The “Pro Model” component plays a key role in guiding users towards subscribing to the premium tier of the AI SaaS application. Here’s a breakdown of how it interacts with Stripe to manage subscriptions:

    1. Triggering the “Pro Model”

    The “Pro Model” component is designed to appear in two scenarios:

    • Free Trial Exhaustion: When a user attempts to use an AI tool but has exceeded their allocated free API calls, the server returns a 403 error (status code for “Forbidden”). This error triggers the onOpen function of the “Pro Model” component, prompting the user to upgrade.
    • User Initiated Upgrade: If a user proactively chooses to upgrade, clicking on an “Upgrade” button (located in the application’s sidebar) directly calls the onOpen function of the “Pro Model,” making it visible.

    2. The “Upgrade” Button and Stripe Interaction

    The “Pro Model” features an “Upgrade” button. When clicked, it triggers the following flow:

    • onSubscribe Function Execution: The button’s onClick event is bound to the onSubscribe function.
    • Loading State Activation: The onSubscribe function first sets the component’s loading state to true, disabling the button to prevent multiple clicks and visually signaling that an operation is in progress.
    • Request to Stripe Route: An Axios GET request is sent to the /api/stripe endpoint. This endpoint acts as a gateway, intelligently determining whether to initiate a new checkout session or redirect the user to the Stripe billing portal.
    • Stripe Checkout or Billing Portal:New Subscription: If the user does not have an existing Stripe customer ID associated with their account, the /api/stripe endpoint creates a Stripe checkout session using stripe.checkout.sessions.create(). This generates a checkout URL, which is sent back to the client in the response.
    • Existing Subscription: If a Stripe customer ID is found, indicating an active or past subscription, the endpoint creates a billing portal session using stripe.checkout.sessions.create(). This returns a billing portal URL.
    • Redirection: The client-side code receives the URL (either checkout or billing portal) and redirects the user’s browser window using window.location.href.

    3. Webhook Integration

    Stripe’s webhooks are essential for receiving asynchronous notifications about events related to subscriptions. The application has a dedicated /api/webhook endpoint to handle these events.

    • Checkout Session Completed: When a new checkout session is successfully completed, Stripe sends a checkout.session.completed event to the webhook endpoint. The handler extracts the user ID from the metadata object (passed during checkout session creation) and creates a new user subscription record in the database.
    • Invoice Payment Succeeded: If a user renews their subscription or an invoice payment is successful, the invoice.payment_succeeded event is triggered. The handler updates the existing user subscription record, updating the price ID and the current period end date.

    4. Visual Feedback and Error Handling

    • Loading State Deactivation: After initiating the Stripe interaction (either checkout or billing portal), the onSubscribe function sets the loading state back to false, re-enabling the “Upgrade” button.
    • Error Handling: The onSubscribe function includes a catch block to handle errors during the Stripe API call. A toast notification is displayed to the user, informing them that something went wrong.
    • Subscription Status Display: On the user’s settings page, the application uses the checkSubscription function to determine whether the user has an active and valid Pro subscription. This information is displayed to the user, informing them of their current plan status.

    By combining the “Pro Model” component, Stripe’s checkout and billing portal functionality, and webhook integration, the AI SaaS application effectively manages user subscriptions and provides a clear path for upgrading to the premium tier.

    The Role of the absoluteURL Function in the Stripe Integration

    The absoluteURL function plays a crucial role in ensuring that Stripe’s checkout and billing portal flows correctly redirect the user back to the AI SaaS application. Here’s why it’s necessary:

    1. Stripe’s Need for Absolute URLs:

    When interacting with Stripe’s checkout and billing portal, you must provide specific URLs for redirecting the user after they complete actions like subscribing or managing their subscription. Stripe requires these URLs to be absolute, meaning they include the full web address (including the protocol, domain, and path).

    Stripe needs absolute URLs because it operates as an external service. It doesn’t have knowledge of your application’s hosting environment or the base URL where it resides. Relative URLs, which only specify the path from the current location, would be meaningless to Stripe.

    2. The absoluteURL Function:

    The absoluteURL function in the sources is a utility function that constructs absolute URLs by combining:

    • The application’s base URL: This is obtained from an environment variable NEXT_PUBLIC_APP_URL. During local development, it’s set to http://localhost:3000. In production, it would point to your deployed application’s URL (e.g., https://your-ai-app.com).
    • The relative path: This is the specific path within your application where you want the user to be redirected. For example, /settings would point to the user’s settings page.

    Here’s the code for the absoluteURL function:

    export function absoluteURL(path: string) {

    return `${process.env.NEXT_PUBLIC_APP_URL}${path}`;

    }

    3. Usage in Stripe Integration:

    The absoluteURL function is used when creating Stripe checkout sessions and billing portal sessions:

    • settingsURL: The code defines a settingsURL variable using absoluteURL(‘/settings’). This ensures that when a user interacts with the Stripe checkout or billing portal, they are redirected back to the correct settings page in the AI SaaS app.
    • stripe.checkout.sessions.create() (Checkout):
    • success_url: This parameter specifies the URL where the user should be redirected after a successful subscription payment.
    • cancel_url: This parameter specifies the URL where the user should be redirected if they cancel the checkout process.
    • stripe.billingPortal.sessions.create() (Billing Portal):
    • return_url: This parameter sets the URL where the user will be returned after interacting with the billing portal (e.g., updating their payment method or canceling their subscription).

    In Summary:

    The absoluteURL function is essential for providing Stripe with complete and valid URLs, enabling correct redirection during checkout and billing portal interactions. It ensures a seamless user experience by returning users to the appropriate location within the AI SaaS application.

    Using GlobalThis.prisma to Prevent Hydration Errors

    The sources illustrate a technique for preventing hydration errors related to Prisma in a Next.js 13 development environment. The core issue stems from the way Next.js handles hot reloading during development, potentially leading to multiple instances of the PrismaClient being created, causing inconsistencies and warnings.

    Understanding the Problem:

    Every time a code change is made and Next.js performs a hot reload, there’s a risk of a new PrismaClient instance being initialized. If components rely on different PrismaClient instances, they might work with inconsistent data or encounter synchronization issues. This can lead to “hydration errors,” where the server-rendered HTML doesn’t match the client-side state after React hydration.

    The Solution: GlobalThis.prisma:

    The code snippet provided in the sources offers a way to mitigate this problem:

    // lib/prismadb.ts

    import { PrismaClient } from ‘@prisma/client’;

    declare global {

    var prisma: PrismaClient | undefined;

    }

    const prismadb = globalThis.prisma || new PrismaClient();

    if (process.env.NODE_ENV !== ‘production’) {

    globalThis.prisma = prismadb;

    }

    export default prismadb;

    Explanation:

    1. Global Variable: A global variable prisma is declared. This variable will hold a single instance of the PrismaClient.
    2. Initialization: The prismadb constant is assigned either the existing globalThis.prisma (if it exists) or a new PrismaClient instance.
    3. Development Environment Check: The code checks if the application is running in a development environment (process.env.NODE_ENV !== ‘production’).
    4. Assigning to globalThis: If in development, the prismadb instance is assigned to the global variable globalThis.prisma. This ensures that subsequent hot reloads reuse the same PrismaClient instance.

    Benefits of This Approach:

    • Single Instance: By storing the PrismaClient instance in a global variable, the code ensures that only one instance is used throughout the application, regardless of hot reloads.
    • Hydration Error Prevention: This consistency in using a single PrismaClient reduces the likelihood of hydration errors, as components are guaranteed to work with the same data and connections.
    • Development Efficiency: Developers avoid unnecessary warnings and errors related to multiple PrismaClient instances, leading to a smoother development workflow.

    Key Points:

    • The use of globalThis.prisma is specifically for development environments to handle hot reloading peculiarities.
    • In production, the globalThis assignment is skipped, allowing Prisma to manage the PrismaClient lifecycle as intended.
    • This technique helps maintain data consistency and prevent potential issues arising from multiple PrismaClient instances during development.

    Leveraging the CN Library for Dynamic Tailwind Styling

    The sources highlight the use of the CN library, imported from add/lib/utils, for managing dynamic class names in Tailwind CSS projects. Here’s why employing this library is beneficial:

    1. Conciseness and Readability:

    When dealing with conditional or dynamically generated class names, using template literals or string concatenation can become cumbersome and difficult to read. The CN library provides a cleaner and more structured approach.

    2. Tailwind-Specific Optimization:

    The CN library is specifically designed for use with Tailwind CSS. It likely leverages tools like clsx or Tailwind’s own internal merging mechanisms to efficiently combine and apply class names. This ensures optimal performance and prevents potential conflicts that might arise from manually manipulating class strings.

    3. Combining Default and Dynamic Classes:

    The sources demonstrate the CN library’s ability to seamlessly merge default Tailwind class names with dynamically generated ones. This allows for a more organized structure where base styles are defined first, followed by conditional or computed class additions.

    Example from the Sources:

    <div className={CN(“text-sm group flex p-3 w-full justify-start font-medium cursor-pointer hover:text-white hover:bg-white”,

    pathname === route.href ? “text-white bg-white/10” : “text-zinc-400”)}>

    {/* … content … */}

    </div>

    In this example, the CN function takes two arguments:

    • Default Classes: A string containing standard Tailwind classes for the <div> element.
    • Conditional Classes: A ternary operator that applies either “text-white bg-white/10” or “text-zinc-400” based on the pathname value.

    The CN library intelligently combines these classes, resulting in a single, optimized class name string that is applied to the element.

    Benefits in Summary:

    • Improved Code Clarity: The CN library makes it easier to read and understand complex styling logic involving dynamic class names.
    • Tailwind Integration: Its integration with Tailwind ensures proper merging and optimization of class names, preventing conflicts or performance issues.
    • Simplified Conditional Styling: It streamlines the process of applying conditional styles based on variables or component states.

    By adopting the CN library, developers can create more maintainable and efficient styling code when working with dynamic Tailwind class names in their Next.js 13 projects.

    Addressing Limitations of the next/image Component

    While the sources don’t explicitly detail the limitations of the next/image component, they do provide a practical example of overcoming one specific constraint. This constraint is related to the requirement of specifying allowed image domains for security and optimization purposes.

    1. The domains Property in next.config.js:

    In the context of building an image generation feature ([1, 2]), the tutorial encounters an error when attempting to display images fetched from an external source (OpenAI’s image generation API). The error message indicates that the src prop provided to the next/image component is not from a valid domain. To address this, the tutorial modifies the next.config.js file to include the following:

    // next.config.js

    module.exports = {

    // … other configurations …

    images: {

    domains: [‘oaidalleapiprodscus.blob.core.windows.net’],

    },

    };

    Explanation:

    • Security and Optimization: The next/image component enforces this restriction for security reasons and to enable image optimization techniques like lazy loading. By default, it only allows images from the same domain as the application itself.
    • Allowing External Domains: When using images from external sources, you must explicitly list the allowed domains in the domains array within the images configuration of your next.config.js file.
    • OpenAI Example: In this case, the tutorial adds the domain oaidalleapiprodscus.blob.core.windows.net to the allowed domains, as this is where the generated images are hosted by OpenAI’s API.

    2. Implications of the domains Property:

    • Security: This property acts as a whitelist, preventing the next/image component from loading images from potentially malicious or untrusted sources.
    • Performance: It enables Next.js to optimize image loading and delivery by applying techniques such as lazy loading and image resizing based on the user’s device.
    • Maintenance: As your application evolves and you integrate with different image providers, you’ll need to update the domains array to ensure that images from those sources are correctly handled.

    In Summary:

    While the tutorial doesn’t exhaustively cover all the limitations of next/image, it effectively demonstrates a common constraint and its solution:

    • Limitation: The next/image component, by default, restricts image loading to the application’s domain for security and performance reasons.
    • Solution: To use images from external sources, you must explicitly specify the allowed domains in the domains property of the images configuration within your next.config.js file.

    By understanding this configuration, you can leverage the power of the next/image component while maintaining security and optimizing image delivery in your Next.js applications.

    Preventing Free Tier Users from Exceeding API Call Limits

    The tutorial implements a robust system for managing and limiting API calls for free tier users, combining database tracking with runtime checks.

    1. Defining the Limit:

    A constant, MAX_FREE_COUNTS, is set to 5, defining the maximum number of API calls allowed for free tier users. This value can be adjusted in the constants.ts file. [1]

    2. Tracking API Usage:

    • Prisma Model: A Prisma model called userAPIlimit is created to store the API usage count for each user. [2] This model includes fields for the user’s ID (userId), their usage count (count), and timestamps for creation and updates.
    • increaseAPIlimit Function: Every time an API route is successfully called, the increaseAPIlimit function is invoked. This function checks if a userAPIlimit record exists for the current user. If it exists, the count is incremented; otherwise, a new record is created with a count of 1. [1, 3]

    3. Enforcing the Limit:

    • checkAPIlimit Function: Before executing any API request, the checkAPIlimit function is called. This function retrieves the userAPIlimit for the current user and compares the count with MAX_FREE_COUNTS. If the count is less than the limit, the function returns true, allowing the API request to proceed. Otherwise, it returns false. [3]
    • API Route Handling: Within each API route, the checkAPIlimit function determines whether the user has exceeded their free tier limit. If the limit is reached, a 403 (Forbidden) response with the message “Free trial has expired” is returned. This signals to the frontend that the user needs to upgrade to a pro plan. [4]

    4. Frontend Integration:

    • 403 Error Handling: The frontend components are designed to handle the 403 error. Upon receiving this error, a premium modal is displayed, prompting the user to upgrade their account. [5]
    • Usage Counter Display: A “Free Counter” component in the sidebar visually displays the user’s remaining free API calls (e.g., “3 / 5 Free Generations”). This counter is dynamically updated whenever an API request is made. [6-8]

    5. Subscription Management:

    • Stripe Integration: The application integrates with Stripe to handle user subscriptions and payments. Once a user subscribes, they are granted unlimited API access. [9-11]
    • checkSubscription Function: The checkSubscription function is used to determine whether a user has an active pro subscription. This function retrieves the user’s subscription information and checks if it is active and has not expired. [12]
    • Disabling Limits for Pro Users: When a user is identified as having an active pro subscription, the API call limits are disabled. The checkAPIlimit function always returns true, allowing unlimited API requests. [13]

    Overall, the tutorial provides a well-structured approach to managing API access for free tier users, leveraging Prisma for data persistence, server-side checks for enforcement, and frontend integration for user feedback and upgrade prompts.

    Handling Responses from Multiple AI Services

    The application interacts with two distinct AI service providers: OpenAI and Replicate. Each provider has its own API structure and response format, requiring specific handling within the application.

    Here’s a breakdown of how the application manages the different responses:

    1. OpenAI:

    • API Routes: The application defines dedicated API routes (/api/conversation, /api/code, /api/image) to handle requests for OpenAI services.
    • Request Formatting: OpenAI’s APIs typically require structured requests, often involving a “messages” array to simulate a conversational flow or provide context.
    • For example, in the /api/conversation route, the frontend sends an array of messages, each with a “role” (user or assistant) and “content”.
    • Similarly, the /api/code route uses an “instruction message” to set the AI’s role as a code generator.
    • Response Parsing: The API routes parse the responses from OpenAI, extracting the relevant data and transforming it into a suitable format for the frontend.
    • For /api/conversation and /api/code, the application extracts the “message” object from the response’s choices array.
    • For /api/image, the application extracts the data array, which contains image URLs, from the response.

    2. Replicate:

    • API Routes: Similar to OpenAI, dedicated API routes (/api/music, /api/video) are used for Replicate services.
    • Request Formatting: Replicate’s APIs generally have a simpler request structure, often accepting a single “prompt” string as input.
    • Response Parsing: The Replicate API routes process the responses to extract the necessary information.
    • For /api/music, the audio property is extracted from the response data.
    • For /api/video, the first item (index 0) is retrieved from the data array, representing the generated video.

    3. Frontend Handling:

    • State Management: The frontend components use React’s useState hook to manage the responses from the AI services. The specific state variable name reflects the type of response, such as messages for conversation and code, images for image generation, and music and video for their respective outputs.
    • Conditional Rendering: Based on the received data, the frontend components conditionally render different elements.
    • For conversation and code, the messages array is iterated over to display the chat history.
    • For images, the images array is used to render a grid of images.
    • For music, an <audio> element is created with the src attribute set to the music state.
    • For video, a <video> element is created with the src attribute set to the video state.

    Key Considerations:

    • Error Handling: The application includes error handling in both the API routes and frontend components. Toasts are used to display user-friendly error messages.
    • Loading States: Loading states are implemented to provide visual feedback to the user while the AI services are processing requests.
    • Data Transformation: The application often transforms the received data from the AI services into a format that is more suitable for display or further processing.

    By employing these strategies, the application effectively handles the distinct response structures and formats of OpenAI and Replicate, ensuring a seamless user experience for various AI-powered features.

    Free Tier Limitations for AI Tool Usage

    The sources outline a system for limiting free tier usage of the AI tools, specifically capping the number of times a user can make API calls to generate content. Here’s a breakdown of these limitations:

    • Maximum Free API Calls: Free tier users are restricted to a maximum of five API calls across all AI tools. This limit is defined by the MAX_FREE_COUNTS constant. [1]
    • Tracking Usage: The application utilizes Prisma, a database toolkit, to persistently track the number of API calls made by each user. Each time a user successfully triggers an AI generation, a counter associated with their account in the Prisma database is incremented. [1, 2]
    • Enforcement: Every API request is subject to a check that compares the user’s current usage count against the MAX_FREE_COUNTS limit. If the user has reached their limit, the API request is rejected with a 403 (Forbidden) error. [3]
    • Frontend Notification: Upon receiving the 403 error, the frontend displays a modal informing the user that their free trial has expired and prompts them to upgrade to a pro plan for unlimited usage. [4]
    • Visual Feedback: The application provides a visual indicator in the sidebar, displaying the user’s current usage count out of the total allowed free calls (e.g., “3 / 5 Free Generations”). This counter dynamically updates after each successful generation. [5, 6]

    Circumventing Free Tier Limitations:

    The primary method for bypassing the free tier limitations is by subscribing to a pro plan.

    • Pro Plan Benefits: A pro subscription, managed via Stripe, grants users unlimited access to all AI tools, removing the API call restrictions. [7, 8]
    • Subscription Detection: The application includes logic to detect whether a user has an active pro subscription. If a pro subscription is detected, the API usage limits are deactivated, permitting unrestricted API calls. [8]

    It’s important to note that while the free tier limitations are in place, exceeding them does not result in any charges. The application simply blocks further API requests and directs the user towards the pro subscription option.

    Understanding router.refresh in the onSubmit Function

    The code router.refresh in the onSubmit function serves a critical role in updating server components after data changes have occurred on the server. Here’s a breakdown of its significance:

    1. Context:

    • Server Components: Next.js 13 introduces the concept of server components, which primarily execute on the server-side and offer performance benefits by reducing client-side JavaScript.
    • Data Fetching: Server components often fetch data from databases or external APIs. This data needs to be synchronized with the user interface, especially after actions that modify this data.
    • onSubmit Handling: In the context of form submissions (using the onSubmit handler), data is typically sent to the server, processed, and potentially stored in a database. The frontend then needs to reflect these changes.

    2. Purpose of router.refresh:

    • Rehydration of Server Components: The router.refresh function, sourced from next/navigation, acts as a trigger to re-run server components and re-fetch data.
    • Synchronization with Server-Side Changes: After an action like submitting a form or modifying data, router.refresh ensures that all server components dependent on that data are re-executed, fetching the updated information from the server.

    3. Example in the Sources:

    • API Limits and Free Counter: The sources demonstrate the use of router.refresh to update the “Free Counter” component after each successful API call. The counter is part of a server component, and router.refresh ensures that the server component fetches the latest usage count from the Prisma database, accurately reflecting the remaining free API calls.
    • Placement in finally Block: In the onSubmit function, router.refresh is typically placed within the finally block. This placement guarantees that server components are rehydrated regardless of whether the API request succeeds or fails, ensuring consistency in the user interface.

    4. Benefits:

    • Simplified Data Synchronization: router.refresh streamlines the process of keeping the frontend in sync with server-side data changes.
    • Improved User Experience: It provides real-time feedback to the user, displaying updated data without requiring manual page refreshes.
    • Code Clarity: By explicitly using router.refresh, the intent to update server components becomes clear in the code.

    In summary, router.refresh is a powerful tool in Next.js for synchronizing server components with data changes on the server. By rehydrating server components after actions like form submissions, it ensures that the frontend displays the most up-to-date information, contributing to a smooth and responsive user experience.

    Identifying Stripe Events in the Webhook Route

    The webhook route in the sources is designed to handle events triggered by Stripe, specifically those related to managing user subscriptions. The code specifically listens for two key Stripe events:

    1. checkout.session.completed: This event is fired when a user successfully completes the checkout process for a new subscription. The webhook uses this event to create a new user subscription record in the Prisma database, linking the Stripe subscription data with the user’s ID.
    2. invoice.payment_succeeded: This event is triggered when a recurring payment for an existing subscription is successful. The webhook captures this event to update the user’s subscription information in the database, particularly the price ID and the current period end date, reflecting the renewal of their subscription.

    Detailed Breakdown of Event Handling:

    1. checkout.session.completed:

    • Data Extraction: Upon receiving this event, the webhook extracts the subscription object from the event data. This object contains detailed information about the newly created subscription.
    • Metadata Retrieval: The webhook then attempts to retrieve the userId from the metadata associated with the checkout session. This userId was originally embedded in the metadata when the checkout session was initiated on the client-side.
    • User ID Validation: If the userId is missing from the metadata, the webhook throws an error and returns a 400 (Bad Request) response, indicating that the user ID is required for processing the subscription.
    • Subscription Creation in Prisma: If the userId is present, the webhook proceeds to create a new userSubscription record in the Prisma database. It populates the record with the user’s ID, the Stripe subscription ID, the customer ID, the price ID, and the current period end date.

    2. invoice.payment_succeeded:

    • Subscription Retrieval: When this event is received, the webhook fetches the Stripe subscription using the subscription ID from the event data.
    • Subscription Update in Prisma: The webhook then locates the existing userSubscription record in the database based on the Stripe subscription ID. It updates this record with the latest price ID and the updated current period end date.

    Key Considerations:

    • Webhook Security: The webhook utilizes a signing secret provided by Stripe to verify that the incoming events are legitimate and originated from Stripe. This prevents malicious actors from spoofing events and potentially manipulating subscription data.
    • Public Route Accessibility: The webhook route is configured as a public route in the Next.js middleware, ensuring that Stripe can access it without requiring authentication. This is essential for Stripe to deliver events to the application.
    • Error Handling: The webhook includes robust error handling using a try-catch block. It returns a 400 (Bad Request) response with an error message if any issues arise during the processing of the Stripe events.

    By focusing on these two specific events, the webhook route effectively manages the creation and renewal of user subscriptions, maintaining synchronization between Stripe’s subscription data and the application’s database. This enables the application to accurately track user subscription status and enforce the limitations of the free tier.

    Enhancing Application Performance: Insights from the Sources

    The sources primarily focus on building the application’s features and do not explicitly address performance optimization techniques. However, based on the information provided and general best practices for web application performance, here are two potential avenues for improvement:

    1. Optimizing Long-Running API Calls:

    Issue: The sources highlight that certain AI models, particularly those relying on external APIs like Replicate AI for music and video generation, can have significant execution times. These long-running processes can lead to timeouts on platforms like Vercel’s Hobby plan and negatively impact user experience.

    Potential Solution: Asynchronous Processing with Webhooks

    • Background Tasks: Instead of waiting for these long-running API calls to complete within the HTTP request-response cycle, the application could delegate them to asynchronous background tasks.
    • Webhook Integration: Services like Replicate AI often offer webhooks that send notifications upon task completion. The application could leverage these webhooks to receive updates on the status of the AI generation process.
    • Frontend Updates: Upon receiving a webhook notification indicating successful generation, the application could update the frontend with the generated content.
    • Benefits: This approach prevents API requests from timing out and allows the application to remain responsive while the AI models run in the background. It also provides a mechanism for delivering real-time progress updates to the user, enhancing their experience.

    Caveats:

    • Implementing asynchronous processing requires additional infrastructure, such as a task queue and a webhook handling mechanism.
    • It introduces complexity in managing the state of AI generation tasks and synchronizing them with the frontend.

    2. Caching Frequently Accessed Data:

    Issue: The sources demonstrate that the application fetches data from various sources, including the Prisma database and the Clerk authentication service. Repeatedly fetching the same data can lead to performance bottlenecks, especially if the data is relatively static.

    Potential Solution: Implementing Caching Strategies:

    • Database Caching: Prisma supports various caching mechanisms, such as query caching and result caching. These can be implemented to reduce the number of database queries and improve response times for data that is frequently accessed but rarely changes.
    • Client-Side Caching: For data that is less dynamic, such as user profile information or static content, client-side caching using browser storage or a service worker can significantly reduce the need for repeated server requests.
    • Benefits: Caching strategies effectively reduce the load on the server and database, leading to faster response times and an overall smoother user experience.

    Caveats:

    • Carefully selecting what to cache and for how long is crucial. Caching outdated data can lead to inconsistencies and inaccuracies in the application.
    • Implementing caching mechanisms adds complexity to the codebase and requires careful consideration of cache invalidation strategies.

    Note: These recommendations are based on general performance optimization principles and may require further investigation and adaptation to the specific needs and architecture of the application.

    Ensuring Server Component Updates after API Calls

    The author utilizes the router.refresh function from next/navigation to keep server components synchronized with data changes resulting from API calls [1, 2]. This technique ensures that the frontend accurately reflects the latest server-side state without requiring manual page refreshes.

    Here’s how it works:

    1. Server Components and Data Fetching: Next.js 13 allows components to be rendered on the server for performance benefits. These server components can fetch data from APIs or databases [2].
    2. API Calls within onSubmit Function: The onSubmit function is responsible for handling form submissions. Within this function, the author makes API calls to process user input, such as sending prompts to the AI models [1, 2]. These API calls potentially update data on the server.
    3. Triggering Server Component Rehydration: To ensure the frontend reflects the updated data after an API call, the author includes router.refresh within the finally block of the onSubmit handler [1, 2].
    4. router.refresh Mechanism: router.refresh instructs Next.js to re-run the server components, effectively re-fetching data from the server [1, 2]. This process ensures that the displayed content is in sync with the latest data stored on the server.
    5. Example: API Limits and Free Counter: The author implements an API limit feature that restricts the number of free generations a user can perform [3]. After each API call, router.refresh updates the “Free Counter” component in the sidebar, accurately displaying the remaining free generations. This counter is part of a server component, and router.refresh ensures it fetches the latest usage count from the Prisma database [4].

    Benefits of router.refresh:

    • Data Synchronization: Simplifies the process of keeping the frontend aligned with server-side changes.
    • Real-Time Feedback: Offers immediate updates to users, enhancing interactivity.
    • Code Clarity: Explicitly indicates the intention to update server components.

    Placement in finally Block:

    • Guarantees server components are rehydrated whether the API call succeeds or fails [2].
    • Ensures consistency in the user interface.

    This approach ensures a seamless user experience, providing real-time feedback and maintaining data consistency between the frontend and backend.

    Managing Stripe Webhooks for Subscription Events

    The sources outline a strategy for handling Stripe webhooks specifically for events related to user subscriptions, ensuring the application’s database remains synchronized with Stripe’s records and accurately reflects the user’s subscription status. This is crucial for enforcing the limitations of the free tier and managing access to premium features. The author focuses on processing two specific events: checkout.session.completed and invoice.payment_succeeded.

    Handling checkout.session.completed Events:

    This event signifies a user’s successful completion of the checkout process for a new subscription. The webhook route designed to handle this event ([1]) performs the following actions:

    1. Subscription Retrieval: It fetches the Stripe subscription details using the subscription ID associated with the checkout session.
    2. User ID Extraction: It retrieves the userId from the metadata attached to the checkout session. Importantly, this userId was embedded in the metadata during the checkout session’s initiation on the client-side ([2]).
    3. User ID Validation: The code checks if the userId is present. If not, it returns a 400 (Bad Request) error, highlighting the requirement of a userId for associating the subscription with a specific user ([3]).
    4. Creating a New Subscription Record: When the userId is available, the webhook proceeds to create a new userSubscription entry in the Prisma database ([3]). This record links the Stripe subscription data with the user’s ID, effectively registering the user’s subscription within the application.

    Handling invoice.payment_succeeded Events:

    This event signals the successful completion of a recurring payment for an existing subscription. The webhook route handles this event to update the user’s subscription details in the database, primarily focusing on updating the price ID and the current period end date to reflect the subscription renewal ([3]). Here’s how the webhook processes this event:

    1. Fetching the Stripe Subscription: It uses the subscription ID provided in the event data to retrieve the updated subscription details from Stripe.
    2. Updating the Existing Subscription: The webhook locates the corresponding userSubscription record in the database based on the Stripe subscription ID and updates it with the latest price ID and the renewed current period end date ([3]).

    Key Considerations and Best Practices:

    • Security: The webhook implementation emphasizes security by utilizing a signing secret provided by Stripe ([1]). This secret is used to verify the authenticity of incoming webhook events, ensuring they originated from Stripe and preventing malicious actors from manipulating subscription data.
    • Public Route Accessibility: The webhook route (/api/webhook) is explicitly configured as a public route in the Next.js middleware ([4]). This configuration allows Stripe to send webhook events to the application without encountering authentication barriers, which are typically in place for routes within the application.
    • Error Handling: The webhook code includes robust error handling through a try-catch block. If any errors occur during the processing of webhook events, the route returns a 400 (Bad Request) response with an appropriate error message, aiding in debugging and providing insight into potential issues ([1]).

    By carefully managing these two specific Stripe webhook events, the author establishes a reliable mechanism for synchronizing user subscription data between Stripe and the application’s database, enabling the application to enforce its subscription model effectively.

    Please note that while the sources do not explicitly mention handling cancellation events, a robust subscription management system would typically include logic for handling customer.subscription.deleted events to reflect cancellations in the application’s database. This might involve updating the userSubscription record to mark the subscription as inactive or deleted, depending on the application’s requirements. You might want to research how to implement this functionality if you are building a similar application.

    Styling Primary Buttons and Progress Bars

    The sources provide a detailed walkthrough of building a SaaS application featuring various AI models. The author demonstrates how to style primary buttons and progress bars to enhance the application’s visual appeal and create a cohesive user experience. The styling process involves utilizing Tailwind CSS for base styles, leveraging the customization options provided by the Shadcn/UI component library, and directly modifying component source code for granular control.

    Primary Buttons: Achieving a Premium Gradient Look

    The author aims to distinguish the “Upgrade” button visually, conveying a sense of exclusivity and encouraging users to subscribe to the premium tier. This is achieved by applying a vibrant gradient background to the button.

    1. Shadcn/UI and Tailwind CSS Integration: The application relies on Shadcn/UI, a React component library built upon Radix UI and Tailwind CSS. This library provides pre-styled, accessible components that can be further customized.
    2. Creating a Custom Button Variant: The author leverages Shadcn/UI’s flexibility by introducing a new button variant named “premium” within the button.tsx component file ([1]). This variant defines the specific styles that will be applied when the variant=”premium” prop is passed to a Button component.
    3. Defining the Gradient: The premium variant utilizes Tailwind CSS classes to create a gradient background. The class bg-gradient-to-r sets a rightward linear gradient, and the from-indigo-500, via-purple-500, and to-pink-500 classes specify the gradient’s color stops ([2]).
    4. Additional Styling: The premium variant also sets the text color to white (text-white) and removes any default border (border-0) for a cleaner appearance ([2]).

    Progress Bars: Reflecting the Application’s Color Theme

    The author uses progress bars to visually represent the remaining free generations available to users. These progress bars are styled to align with the application’s overall color palette, creating a consistent and visually appealing design.

    1. Shadcn/UI’s Progress Component: The application employs the Progress component provided by Shadcn/UI, which offers basic styling and functionality out of the box.
    2. Global CSS Variables: The author sets a global CSS variable named –primary to define the primary color of the application ([3]). This variable holds an HSL color value representing a light purple shade.
    3. Inheriting the Primary Color: Shadcn/UI’s Progress component automatically inherits the value of the –primary CSS variable, applying it as the background color of the progress bar. This ensures the progress bar’s color matches the primary buttons and other elements styled using the –primary variable.
    4. Adjusting Height: The author applies the h-3 class to the Progress component to adjust its height, making it thinner for a subtle and less intrusive appearance ([4]).

    Summary

    The author styles primary buttons and progress bars by:

    • Using Tailwind CSS for base styles.
    • Creating a custom “premium” button variant with a gradient background using Tailwind CSS classes.
    • Leveraging the Progress component from Shadcn/UI and setting its color using a global CSS variable (–primary).

    This approach combines the convenience of pre-styled components with the flexibility of Tailwind CSS and direct component customization, allowing the author to achieve the desired visual aesthetic and maintain a cohesive design language throughout the application.

    ChatCNUI’s Appeal: Flexibility and Ownership

    The author highlights the choice of ChatCNUI as the CSS framework for this project, emphasizing its distinct approach compared to other popular options like Chakra UI or Material UI. ChatCNUI, according to the author, isn’t strictly a component library but rather a system that prioritizes customizability and control over the component structure.

    Here’s why the author favors ChatCNUI:

    • Accessible Component Source Code: Unlike frameworks like Material UI or Chakra UI, where components reside within the node_modules directory, ChatCNUI places its components directly within the project’s components folder [1]. This accessibility grants developers the ability to directly modify the source code of components, tailoring them to their specific needs and preferences.
    • Enhanced Customization: This direct access facilitates a deeper level of customization than what’s typically achievable with traditional component libraries [1]. Developers can freely rename elements, adjust styles, and modify the underlying logic of components to align perfectly with their project’s requirements.
    • Ownership and Flexibility: The author underscores the benefit of “complete ownership of your component system” [2]. By having the component source code readily available, developers gain a greater sense of control and can make changes without being constrained by the limitations imposed by pre-built components in other frameworks.
    • Seamless Integration with Tailwind CSS: ChatCNUI works harmoniously with Tailwind CSS, allowing developers to combine utility-first styling with customizable components [3]. This integration simplifies the process of creating a unified and visually appealing user interface.

    The author demonstrates this customization capability by modifying the destructive variant of the Button component, renaming it to Danger and showcasing how this change immediately reflects in the application’s code and user interface [2]. This example highlights the ease with which developers can adapt ChatCNUI components to their preferred terminology and styling conventions.

    While the sources don’t explicitly compare ChatCNUI to other frameworks in terms of performance or bundle size, the author’s primary rationale for choosing ChatCNUI revolves around the unparalleled flexibility and control it offers, empowering developers to shape the component system according to their project’s unique demands.

    Free API Call Limits

    The sources indicate that users of the service are granted five free API calls. The application implements a system to track and limit the usage of these free calls, prompting users to subscribe to a paid plan once they have exhausted their free quota.

    Here’s how the free API call limit is implemented:

    1. Max_free_counts Constant: A constant named Max_free_counts is defined within a constants.ts file, setting the maximum number of free calls allowed to five (). This constant serves as a central point of control for easily modifying the limit in the future.
    2. User API Limit Tracking: The application uses Prisma, an ORM (Object Relational Mapper), to interact with a MySQL database hosted on PlanetScale. A Prisma model named userAPIlimit is created to store the API call usage for each user (). This model tracks the userId, the count of API calls made, and timestamps for record creation and updates.
    3. increaseAPIlimit Utility Function: A utility function named increaseAPIlimit is responsible for incrementing a user’s API call count each time they interact with one of the AI models (). This function retrieves the user’s ID using Clerk, an authentication provider, and then either updates the existing userAPIlimit record for that user, increasing the count, or creates a new record if one doesn’t exist, initializing the count to one.
    4. checkAPIlimit Utility Function: Another utility function, checkAPIlimit, determines whether a user has reached their free call limit (). This function fetches the userAPIlimit record for the currently authenticated user and compares the recorded count against the Max_free_counts constant. If the user’s count is less than the maximum allowed or no record exists (indicating they haven’t used any calls), the function returns true, permitting access to the API. Otherwise, it returns false, signaling that the user has exhausted their free calls and should be prompted to upgrade.
    5. API Route Protection: The API routes responsible for handling requests to the AI models utilize the checkAPIlimit function to enforce the free call restriction. If a user attempts to exceed their limit, the route returns a 403 (Forbidden) error, indicating their free trial has expired (). This error triggers the display of a premium subscription modal, prompting the user to upgrade.
    6. Subscription Integration: The application integrates with Stripe, a payment processing platform, to manage subscriptions. Once a user subscribes, the checkAPIlimit function effectively bypasses the restriction, granting them unlimited access to the AI models as they are considered a paid subscriber.

    Through this mechanism, the application effectively tracks and limits free API call usage, guiding users towards subscribing to unlock unlimited access to its features.

    Integrating Customer Support with Crisp

    The sources explain how to integrate Crisp, a customer support platform, into the SaaS application. This integration provides a real-time chat interface for users to connect with support staff and receive assistance. The implementation process involves installing the Crisp SDK, configuring the Crisp chat widget, and embedding it within the application’s layout.

    Here’s a step-by-step breakdown of the integration:

    1. Crisp Account and Website ID: The first step is to create a Crisp account and obtain the Crisp Website ID. This ID, a unique identifier for the application’s Crisp integration, is essential for configuring the chat widget. The author demonstrates how to locate this ID within the Crisp dashboard and copy it for later use.
    2. Installing the Crisp SDK: The application utilizes the crisp-sdk-web package, a JavaScript SDK for interacting with the Crisp API, to implement the chat functionality. This package is installed via npm:
    3. npm install crisp-sdk-web
    4. Creating the crisp-chat Component: A dedicated React component named CrispChat is created to handle the initialization and configuration of the Crisp chat widget. This component leverages the useEffect hook to perform actions after the component renders:
    5. import { useEffect } from ‘react’;
    6. import crisp from ‘crisp-sdk-web’;
    7. export const CrispChat = () => {
    8. useEffect(() => {
    9. crisp.configure(‘<YOUR_CRISP_WEBSITE_ID>’);
    10. }, []);
    11. return null;
    12. };
    13. Within the useEffect hook:
    • crisp.configure() initializes the Crisp SDK with the Crisp Website ID obtained earlier.
    • The empty dependency array ([]) ensures this configuration runs only once when the component mounts.
    • The component returns null as it doesn’t render any visible elements; its purpose is to set up the chat functionality behind the scenes.
    1. Creating the CrispProvider Component: A CrispProvider component acts as a wrapper for the CrispChat component. This provider ensures that the Crisp chat widget is initialized within the application’s client-side environment, preventing hydration errors that can occur when server-side rendering interacts with client-side libraries:
    2. // …imports
    3. export const CrispProvider = () => {
    4. return <CrispChat />;
    5. };
    6. Embedding in the App Layout: To make the chat widget available throughout the application, the CrispProvider component is included within the main layout component (app/layout.tsx). This ensures the chat widget loads and is accessible on every page:
    7. // …imports
    8. export default function RootLayout({ children }: { children: React.ReactNode }) {
    9. return (
    10. <html>
    11. <head />
    12. <body>
    13. <CrispProvider />
    14. {/* …other layout elements */}
    15. {children}
    16. </body>
    17. </html>
    18. );
    19. }

    By following these steps, the SaaS application seamlessly integrates Crisp, providing users with a readily accessible way to communicate with support personnel for assistance. The chat widget’s appearance and behavior can be further customized within the Crisp dashboard to align with the application’s branding and user experience guidelines.

    Unlocking the Power of Genius Pro

    The sources primarily focus on building the Genius SaaS platform and its functionalities, with specific details about the Genius Pro subscription being somewhat limited. However, the available information paints a clear picture of what a Genius Pro subscription would offer:

    Unlimited AI Generations: One of the key benefits of subscribing to Genius Pro is the removal of the free API call limitations. While free users are restricted to five API calls, Genius Pro grants subscribers unlimited access to the platform’s AI capabilities (). This unrestricted access allows Pro users to leverage the various AI models without encountering usage restrictions, enabling them to fully explore the potential of Genius’s functionalities.

    Access to All AI Tools: The Genius Pro subscription presumably unlocks the full suite of AI tools available on the platform. The sources demonstrate the development and implementation of five distinct AI models:

    • Image Generation: Users can generate images from text prompts using an image generation model.
    • Video Generation: Users can create videos from text descriptions using a video generation model.
    • Conversation: Users can engage in conversations with a conversational AI model, asking questions and receiving informative responses.
    • Music Generation: Users can generate musical pieces using a music generation model, specifying desired instruments and styles.
    • Code Generation: Users can generate code snippets using a code generation model, providing descriptive instructions for the desired code functionality.

    Free users are likely limited in their access to these tools, either facing restricted usage or complete unavailability. Genius Pro subscribers, however, would have unrestricted access to all five AI models, empowering them to utilize the platform’s full creative and practical potential.

    Priority Support: While the sources don’t explicitly mention this, it’s reasonable to infer that Genius Pro subscribers might receive priority customer support. The platform integrates Crisp, a customer support platform, offering real-time chat assistance. Pro subscribers might be given preferential treatment, receiving faster responses and dedicated support channels, enhancing their overall experience and resolving any issues promptly.

    Additional Features (Possible): The sources don’t detail other potential features included in Genius Pro. However, based on common practices in SaaS platforms, additional features might include:

    • Higher Resolution Outputs: Pro subscribers could benefit from higher resolution images, videos, and audio files generated by the AI models.
    • Extended Customization Options: Pro users might have access to advanced customization settings for the AI models, allowing for greater control over the generated output.
    • Early Access to New Features: Genius Pro could provide subscribers with early access to new AI models and features, giving them an edge in leveraging the latest advancements.

    It’s important to note that these additional features are speculative and not explicitly mentioned in the sources.

    The Genius Pro subscription, by providing unlimited access to AI generations and a comprehensive suite of tools, aims to empower users with the full creative and practical capabilities of the platform. While details on specific features remain limited, the available information highlights the subscription’s focus on unlocking the full potential of Genius’s AI-powered functionalities.

    The AI Toolkit of “Genius”

    The sources provide a comprehensive overview of the development process and features of the Genius SaaS platform, highlighting the various AI tools it incorporates. These tools are designed to empower users with AI-driven capabilities for content creation and problem-solving. Here’s a detailed examination of the AI tools offered by Genius:

    • Image Generation: This tool leverages an image generation AI model, likely based on Stable Diffusion or a similar architecture, to generate images from text prompts. Users can input a descriptive phrase or sentence, such as “a horse in the Swiss Alps” [1], and the AI model processes this text to create a visually corresponding image. The application offers options to customize the number of images generated and their resolution [1], providing flexibility in tailoring the output to specific needs.
    • Video Generation: Genius also includes a video generation tool powered by a dedicated AI model. This tool enables users to transform text descriptions into short video clips. Similar to the image generation process, users provide a text prompt, such as “clownfish swimming around a coral reef” [2], and the AI model generates a video that visually represents the described scene. The sources indicate the use of the Zeroscope model hosted on Replicate, an AI model platform, for video generation [2].
    • Conversation: A conversational AI model, powered by OpenAI’s GPT-3.5-turbo [3], forms the backbone of the Genius conversation tool. This tool allows users to engage in natural language conversations with the AI, asking questions, seeking information, or simply engaging in casual dialogue. The AI model is trained on a massive dataset of text and code, enabling it to understand and respond to a wide range of prompts and questions, offering informative and contextually relevant answers.
    • Music Generation: The music generation tool in Genius leverages AI to create musical pieces from text prompts. Users can specify the desired genre, instruments, or style through text descriptions. The application utilizes the “Riffusion” model hosted on Replicate for music generation [4]. This model converts text prompts, like “piano solo” [5], into audio files, allowing users to experiment with different musical ideas and generate unique compositions.
    • Code Generation: Genius incorporates a code generation tool powered by OpenAI’s GPT-3.5-turbo model [6]. This tool assists users in generating code snippets based on descriptive instructions. Users input a text prompt outlining the desired code functionality, such as “write simple toggle button using react hooks” [7], and the AI model generates the corresponding code in a Markdown format for easy readability and integration into projects.

    These five AI tools, spanning image and video generation, conversational AI, music composition, and code generation, showcase Genius’s comprehensive approach to empowering users with AI-driven capabilities. By integrating these tools into a single platform, Genius offers a versatile toolkit for creative expression, information gathering, and technical assistance.

    Enhancing User Experience through Webhooks in the Genius Application

    The sources focus primarily on building the Genius application and implementing various functionalities, including AI models, subscription management, and customer support. However, the sources do not explicitly discuss using webhooks to enhance the user experience.

    While webhooks are not directly mentioned, the sources do provide insights into areas where webhooks could potentially be employed to improve the application’s functionality and user experience.

    For instance, the AI models, especially video and music generation, can have significant processing times. Users currently need to wait for the model to complete its operation, which can lead to a less than ideal user experience. Implementing webhooks could address this issue. Here’s a potential use case:

    • Asynchronous Processing and Notifications: A webhook could be triggered when an AI model completes its task. This webhook could then send a notification to the user, informing them that their generated content is ready. This approach would eliminate the need for users to constantly check the application for updates, improving their overall experience.

    It’s important to note that this is a hypothetical example, and the sources do not mention the actual implementation of webhooks in the Genius application.

    The sources do describe the use of Stripe webhooks for managing subscriptions and updating user data upon successful payments. This implementation showcases the potential of webhooks for handling background processes and ensuring data consistency, but it doesn’t directly impact the user experience in the same way that AI model processing notifications would.

    The Foundation of Genius’s Interface: Shadcn/ui

    The sources explicitly state that the Genius application relies on shadcn/ui for constructing its user interface. While often referred to as a component library, shadcn/ui operates differently from traditional UI frameworks like Material UI or Chakra UI [1, 2].

    Here’s a breakdown of how shadcn/ui contributes to Genius’s user interface:

    • Not a Traditional Component Library: Unlike conventional component libraries that package pre-built components within node modules, shadcn/ui functions more as a facilitator for creating and customizing components directly within the project’s codebase [1, 2].
    • Component Ownership and Modifiability: Shadcn/ui provides a foundation for building components, giving developers complete control over the code and styling. Components reside within the project’s components folder, allowing for direct modification and tailoring to the application’s specific needs [1, 2].
    • Seamless Integration with Tailwind CSS: Shadcn/ui seamlessly integrates with Tailwind CSS, a utility-first CSS framework, to provide a robust styling system. This integration enables developers to leverage Tailwind’s extensive utility classes while customizing components according to their design preferences [1, 2].
    • Flexibility and Customization: Shadcn/ui emphasizes flexibility and customization. Developers can readily rename, modify, or extend the provided components to align with the application’s visual identity and functional requirements [2].
    • CLI for Component Management: Shadcn/ui offers a command-line interface (CLI) for adding and managing components. This CLI simplifies the process of integrating new components into the project [1, 2].
    • Manual Component Addition: While the CLI streamlines component management, developers can also manually add components by copying code snippets from the shadcn/ui documentation [1].

    The sources demonstrate the use of several shadcn/ui components, including:

    • Button: Used for interactive elements like the “Generate” button for AI model prompts and the “Upgrade” button for subscription prompts [1-3].
    • Sheet: Utilized for creating a drawer-like sidebar that slides in from the side, particularly for mobile navigation [4].
    • Card: Employed for visually grouping and displaying content, such as the AI tool cards on the dashboard and the testimonials on the landing page [5, 6].
    • Progress: Used to visually represent the progress of a task, specifically the API call usage in the free tier [7].
    • Dialog: Implemented for creating modal windows, like the “Upgrade to Genius” modal triggered when a user exceeds their free API call limit [8].
    • Badge: Utilized for displaying small labels or tags, such as the “Pro” badge on the upgrade modal [9].
    • Form Field, Form Item, Form Control, Input, Select: Employed for building interactive forms for user input, like the AI model prompt forms and the subscription checkout form [10, 11].

    Shadcn/ui’s role in the Genius application extends beyond providing pre-built components. It establishes a structured approach to component development, empowering developers to build a custom UI tailored to the application’s unique requirements while leveraging the benefits of Tailwind CSS for styling.

    Tailwind CSS: The Styling Powerhouse of Genius

    The sources and the conversation history highlight that the Genius application uses Tailwind CSS for styling its user interface. Tailwind CSS is not a traditional component library; instead, it’s a utility-first CSS framework. This means it provides a vast collection of pre-defined CSS classes that developers can directly apply to HTML elements, enabling rapid UI development and customization.

    Here’s a deeper look into how Tailwind CSS shapes the Genius application’s style:

    • Utility Classes for Fine-Grained Control: Tailwind CSS offers a comprehensive set of utility classes for controlling layout, typography, colors, spacing, shadows, borders, and more. Instead of writing custom CSS rules, developers can compose these utility classes directly within the HTML, streamlining the styling process.
    • Configuration and Customization: While Tailwind CSS comes with pre-defined styles, it allows extensive customization through a tailwind.config.js file. Developers can adjust color palettes, font families, breakpoints, and other styling aspects to match the application’s design language.
    • Responsive Design Made Easy: Tailwind CSS incorporates a mobile-first approach to responsive design. Its utility classes include responsive modifiers that enable developers to tailor styles for different screen sizes, ensuring a consistent and optimal user experience across various devices.
    • Integration with Shadcn/ui: Tailwind CSS plays a crucial role in the Genius application’s integration with Shadcn/ui. Shadcn/ui provides a foundation for building components, and Tailwind CSS serves as the styling engine, providing the utility classes needed to customize the appearance of those components.

    The sources provide several examples of Tailwind CSS usage within the Genius application:

    • Layout and Spacing: Classes like flex, items-center, justify-center, space-y-4, px-4, and py-36 are used to control the arrangement and spacing of elements on the page.
    • Typography: Classes like text-4xl, font-extrabold, text-white, and text-muted-foreground are used to style text elements, adjusting font sizes, weights, and colors.
    • Colors and Backgrounds: Classes like bg-gradient-to-r, from-purple-400, to-pink-600, and text-primary are used to apply colors and gradients to elements.
    • Borders and Shadows: Classes like border, border-black/10, rounded-lg, and hover:shadow-md are used to add visual embellishments to elements, controlling borders, border-radius, and shadow effects.

    By leveraging Tailwind CSS’s extensive utility class system, the developers of the Genius application have achieved a flexible and maintainable styling solution. This approach allows for rapid UI development, easy customization, and ensures responsiveness across various devices.

    Shadcn/ui: The Building Blocks of Genius’s User Interface

    The sources and the conversation history clearly indicate that the shadcn/ui framework is used to create the UI components in the Genius application. Shadcn/ui, while often referred to as a component library, distinguishes itself from traditional UI frameworks like Material UI or Chakra UI in its approach to component creation and management.

    Here’s a detailed explanation of how shadcn/ui empowers the development of Genius’s user interface:

    • Beyond Pre-Built Components: Shadcn/ui moves away from the concept of pre-packaged components hidden within node modules. Instead, it provides a foundation for constructing components directly within the project’s codebase, giving developers greater control over their structure and appearance.
    • Component Source Code Accessibility: A key advantage of shadcn/ui is that the source code for its components resides within the project’s components folder. This accessibility empowers developers to directly modify and tailor the components to align perfectly with the application’s specific design requirements and functional nuances.
    • Synergy with Tailwind CSS: Shadcn/ui seamlessly integrates with Tailwind CSS, the utility-first CSS framework responsible for styling Genius’s interface. This integration allows developers to leverage Tailwind’s vast collection of utility classes to customize the look and feel of shadcn/ui components, achieving a consistent and maintainable styling solution.
    • Customization as a Core Principle: Flexibility and customization are at the heart of shadcn/ui. Developers have the freedom to rename, restructure, extend, or completely overhaul the provided components to match the application’s visual identity and functional needs. This adaptability ensures that the UI remains cohesive and aligned with the overall design vision.
    • CLI for Streamlined Workflow: Shadcn/ui offers a command-line interface (CLI) that simplifies the process of adding and managing components. Developers can use simple commands to integrate new components into the project, streamlining the development workflow.
    • Manual Component Integration: While the CLI facilitates component management, shadcn/ui also allows for manual component addition. Developers can copy code snippets from the shadcn/ui documentation and integrate them directly into their project, providing flexibility in how components are incorporated.

    The sources showcase the use of various shadcn/ui components within the Genius application:

    • Button: Employed for interactive elements, including buttons like “Generate,” “Upgrade,” and those within the navigation bar. [1-9]
    • Sheet: Used to create the drawer-like sidebar that slides in from the side, specifically for mobile navigation. [4, 10]
    • Card: Implemented for visually grouping and presenting content, as seen in the AI tool cards on the dashboard, the testimonial sections on the landing page, and the visual representation of tools in the upgrade modal. [11-14]
    • Progress: Utilized to visually display the progress of a task, particularly for indicating the API call usage within the free tier. [6]
    • Dialog: Employed to create modal windows, such as the “Upgrade to Genius” modal that appears when a user reaches their free API call limit. [15, 16]
    • Badge: Used to display concise labels or tags, exemplified by the “Pro” badge on the upgrade modal. [17]
    • Form-Related Components: Components like Form Field, Form Item, Form Control, Input, and Select are used extensively to construct interactive forms throughout the application, such as the AI model prompt forms and the subscription checkout form. [5, 18-20]

    Shadcn/ui’s role in the Genius application transcends merely supplying pre-built components. It provides a structured and adaptable framework for crafting a bespoke user interface tailored to the application’s distinct requirements, while seamlessly integrating with Tailwind CSS for streamlined styling. This approach fosters a balance between pre-built efficiency and customizability, allowing developers to create a visually appealing and highly functional user experience.

    A Multifaceted AI Platform: Exploring the Key Features of Genius

    The sources describe the development process of Genius, an AI-powered SaaS application offering a suite of AI tools. Let’s explore the key features that make Genius a unique and powerful platform:

    • Five Core AI Tools: Genius provides access to five distinct AI models:
    • Conversation Model: This chatbot-like tool allows users to interact with a sophisticated AI capable of answering questions, providing information, and engaging in natural language conversations.
    • Code Generation Model: This tool enables users to generate code snippets in various programming languages using descriptive text prompts.
    • Image Generation Model: This tool allows users to create images based on textual descriptions, turning their imagination into visual representations.
    • Video Generation Model: This tool empowers users to generate short videos from textual prompts, bringing dynamic visuals to life.
    • Music Generation Model: This tool allows users to create musical pieces based on descriptive prompts, exploring the realm of AI-composed music.
    • Freemium Model and Subscription Tier: Genius employs a freemium business model, offering a free tier with limited usage and a paid “Pro Plan” subscription tier.
    • Free Tier: Allows users to experiment with the platform and try out the AI models, but with restrictions on the number of generations per AI tool.
    • Pro Plan: Grants users unlimited access to all AI tools and functionalities, removing the usage restrictions of the free tier.
    • Stripe Integration for Secure Payments: Genius leverages Stripe, a widely-used payment processing platform, to handle secure and seamless subscription payments.
    • Checkout Page: Stripe’s checkout page is integrated into the application, providing a familiar and trusted experience for users making payments.
    • Subscription Management: The application includes settings for managing subscriptions, including the ability to upgrade, downgrade, or cancel the Pro Plan.
    • Customer Support via Crisp: Genius incorporates Crisp, a customer support platform, to enhance the user experience and provide assistance.
    • Real-time Chat: Crisp enables users to connect with support agents in real-time, receiving prompt assistance with any issues or inquiries.
    • User Authentication with Clerk: Genius employs Clerk for user authentication, streamlining the login and registration processes.
    • Multiple Authentication Providers: Clerk supports various authentication methods, including Google, GitHub, and email/password combinations, offering flexibility to users.
    • Secure and Seamless Login: Clerk provides a secure and streamlined login experience, allowing users to access the platform quickly.
    • User-Friendly Interface: Genius boasts a user-friendly and visually appealing interface built with modern technologies.
    • Shadcn/ui Component Library: The UI relies on Shadcn/ui, a flexible component framework that allows for customization and integration with Tailwind CSS.
    • Tailwind CSS for Styling: Tailwind CSS, a utility-first CSS framework, provides extensive pre-defined classes for styling elements and components, ensuring responsive design and a polished look.

    The sources focus primarily on the development aspects of Genius, but they showcase a well-structured and feature-rich AI platform designed for accessibility and ease of use. The combination of a freemium model, secure payment processing, integrated customer support, and a user-friendly interface makes Genius an attractive solution for individuals and businesses seeking to explore and leverage the power of AI.

    Monitoring Usage in the Freemium Model: The Role of increaseAPIlimit

    The increaseAPIlimit function plays a crucial role in managing the usage of AI tools by free tier users in the Genius application. The sources highlight that Genius operates on a freemium model, offering a free tier with limited usage and a paid Pro Plan with unlimited access. To enforce these usage limits, the application needs a mechanism to track how many times a free tier user has accessed each AI tool. This is where the increaseAPIlimit function comes in.

    Here’s a breakdown of how increaseAPIlimit contributes to managing free tier usage:

    • Tracking API Calls: Every time a free tier user makes a request to one of the AI tool APIs (e.g., conversation, code generation, image generation), the increaseAPIlimit function is invoked. This function is responsible for incrementing a counter associated with that user, essentially logging each API call.
    • User API Limit Model: To store and manage these API call counts, Genius uses a database model called userAPIlimit. Each record in this model represents a free tier user and their corresponding usage count for the AI tools.
    • Prisma ORM for Database Interactions: The sources indicate that Genius leverages Prisma, an Object-Relational Mapping (ORM) tool, to interact with the database. Prisma simplifies database operations by allowing developers to work with data using JavaScript objects and methods.
    • Steps Involved in increaseAPIlimit: The increaseAPIlimit function performs the following steps:
    1. User Identification: It first retrieves the user ID of the user making the API request. This is likely achieved using the Clerk authentication library, which handles user logins and sessions.
    2. API Limit Retrieval: The function then queries the userAPIlimit model in the database to retrieve the existing API limit count for the identified user.
    • Updating or Creating a Record:If a record already exists for the user, the function updates the count, incrementing it by one to reflect the new API call.
    • If no record is found, implying it’s the user’s first API call, the function creates a new record in the userAPIlimit model, initializing the count to one.
    • Integration with API Routes: The increaseAPIlimit function is strategically integrated into each of the API routes for the AI tools. This ensures that every time an API request is processed, the user’s usage count is updated accordingly.

    By meticulously tracking API calls, increaseAPIlimit empowers Genius to enforce usage limits on the free tier, ensuring the sustainability of the freemium model. When a user reaches the maximum allowed calls within the free tier, the application can prompt them to upgrade to the Pro Plan for unlimited access.

    This approach aligns with the broader SaaS strategy of offering a compelling free tier to attract users, while providing a clear path to a paid subscription for those seeking unrestricted access and enhanced functionalities.

    Empowering User Communication: Crisp as the Customer Support Backbone in Genius

    The sources reveal that Crisp is the technology employed to provide customer support within the Genius application. Crisp is a customer support platform designed to facilitate communication between businesses and their users.

    Here’s a detailed look at how Crisp enhances the user experience in Genius:

    • Real-time Chat Integration: Crisp’s primary functionality is its real-time chat feature. This integration enables Genius users to initiate conversations with support agents directly within the application. This immediacy in communication can be crucial for addressing user issues, answering questions, and providing guidance, ultimately enhancing user satisfaction.
    • Seamless User Experience: The integration of Crisp into Genius’s interface is designed to be unobtrusive yet easily accessible. The sources mention a Crisp icon located in the lower left corner of the application. This placement ensures that the support chat is readily available without disrupting the user’s workflow.
    • Real-time Dashboard for Support Agents: On the backend, Crisp provides support agents with a real-time dashboard that aggregates incoming user messages. This centralized view allows agents to efficiently manage conversations, track user issues, and provide timely responses.
    • Example of Crisp in Action: The sources demonstrate the use of Crisp by simulating a user reporting a problem with image generation. A message sent via Crisp is shown to immediately appear on the Crisp dashboard, highlighting the real-time nature of the communication.

    The integration of Crisp into Genius signifies a commitment to providing a supportive and user-centric experience. By offering a direct channel for communication, Genius can proactively address user concerns, gather feedback, and foster a stronger connection with its user base.

    Simplifying Secure Access: Clerk as the Authentication Gatekeeper for Genius

    The sources explicitly state that Clerk is the technology used to provide user authentication in the Genius application. Clerk is an authentication-as-a-service platform that simplifies the implementation of secure user logins and registrations, allowing developers to focus on core application features.

    Here’s a closer look at how Clerk facilitates authentication in Genius:

    • Seamless Integration with Next.js App Router: The sources emphasize that Genius is built using the app directory structure (App Router) introduced in Next.js 13. Clerk provides dedicated support for this new routing paradigm, ensuring smooth integration and functionality.
    • Multiple Authentication Providers: Clerk’s strength lies in its support for various authentication methods. Genius leverages this flexibility by enabling users to log in using their existing accounts from providers like Google and GitHub, or through traditional email/password combinations. This broadens the application’s reach and accommodates diverse user preferences.
    • Focus on Core Application Development: By using Clerk, the developer of Genius avoids the complexities of building authentication from scratch. This outsourcing of a critical but often time-consuming aspect of development allows for greater focus on building the core AI functionalities that differentiate Genius.
    • User-Friendly Interface: Clerk provides pre-built UI components, such as the SignIn and SignUp components, that streamline the authentication flow. These components are visually appealing and designed for intuitive user interaction.
    • Protection of Sensitive Routes: Clerk plays a crucial role in protecting routes within Genius that require user authentication. The sources demonstrate how Clerk’s middleware, integrated into Next.js, prevents unauthorized access to the application’s dashboard. Users are automatically redirected to the sign-in page if they attempt to access protected routes without logging in.
    • Simplified User Management: The sources highlight the use of Clerk’s UserButton component, which displays the currently logged-in user and provides options for managing their account. This component simplifies actions like signing out and potentially accessing other account-related settings.

    In summary, Clerk acts as a robust and user-friendly authentication layer within Genius. By handling the complexities of user management, Clerk frees up the developer to concentrate on delivering a seamless and secure experience for users interacting with the platform’s diverse set of AI tools.

    A Synergy of Modern Technologies: Constructing the Front-End of Genius

    The sources provide a detailed walkthrough of building the Genius application, focusing primarily on the back-end logic and API integrations. While they don’t explicitly name a single primary technology for the front-end, they do highlight the use of several key technologies working in synergy to construct the user interface:

    • Next.js 13: Next.js serves as the foundational framework for the entire Genius application, encompassing both the front-end and back-end. Next.js is a React-based framework that offers server-side rendering, static site generation, built-in routing, and other features that streamline web development.
    • App Router (app Directory): The sources emphasize the use of the new app directory structure in Next.js 13, often referred to as the App Router. This structure provides enhanced features for nested routing, layouts, server components, and improved performance.
    • Server Components: The sources demonstrate the use of server components within Genius. Server components execute on the server, allowing for direct data fetching from databases and APIs without the need for client-side hydration, often resulting in faster initial page loads and improved SEO.
    • Client Components: Genius also utilizes client components, which run in the user’s browser and are responsible for interactivity and dynamic updates. Client components are used for elements like forms, buttons, and real-time updates to the user interface.
    • React: As a React-based framework, Next.js leverages React, a JavaScript library for building user interfaces. React’s component-based architecture enables developers to break down complex UIs into smaller, reusable pieces, making development more organized and maintainable.
    • Shadcn/ui Component Library: Shadcn/ui emerges as a central player in styling the Genius front-end. Shadcn/ui is a component library built on top of Tailwind CSS, providing a collection of pre-designed, customizable, and accessible components.
    • Flexibility and Customization: Shadcn/ui components offer a high degree of flexibility, allowing developers to tailor their appearance and behavior using props and Tailwind CSS classes. This is in contrast to some component libraries that provide more rigid, pre-styled components.
    • Direct Access to Component Code: A notable advantage of Shadcn/ui highlighted in the sources is its approach to component management. Unlike some component libraries that hide component code within node_modules, Shadcn/ui places the component code directly within the project’s components folder. This grants developers complete control over the appearance and behavior of components, enabling deep customization and modifications.
    • Tailwind CSS: Tailwind CSS is a utility-first CSS framework that provides a vast set of pre-defined CSS classes. These classes can be directly applied to HTML elements, streamlining styling and eliminating the need for writing custom CSS in many cases.
    • Integration with Shadcn/ui: The sources showcase how Shadcn/ui seamlessly integrates with Tailwind CSS, allowing developers to combine pre-designed components with the flexibility and convenience of Tailwind’s utility classes.
    • Responsive Design: Tailwind’s responsive modifiers (e.g., sm, md, lg) enable developers to create user interfaces that adapt smoothly to different screen sizes, ensuring an optimal experience on desktops, tablets, and mobile devices.
    • Lucid React Icon Library: For incorporating icons into the user interface, Genius employs Lucid React, an icon library providing a wide range of scalable vector icons. These icons enhance the visual appeal and clarity of the application’s UI.
    • Typewriter Effect Library: The sources showcase the use of the Typewriter Effect library to create animated text that simulates typing. This effect is employed on the landing page to draw attention to the application’s key features.
    • Clerk UI Components: Clerk, the authentication provider, offers pre-built UI components like SignIn, SignUp, and UserButton. These components simplify the integration of authentication flows and user management features into the front-end.

    In conclusion, the Genius application’s front-end is a well-crafted combination of modern technologies. Next.js forms the framework, React provides the component-based structure, Shadcn/ui contributes styled and customizable components, Tailwind CSS empowers styling, and additional libraries like Lucid React and Typewriter Effect add visual flair and interactivity. The developer’s choice to leverage Shadcn/ui’s direct access to component code demonstrates a preference for control and flexibility in shaping the application’s look and feel.

    Shaping the Code Generator’s Behavior: The Role of the “Instruction Message”

    The sources provide a clear explanation of the purpose of the “instruction message” in the code generation API route within the Genius application. This message acts as a guiding force, shaping the behavior of the OpenAI language model (GPT-3.5-turbo) responsible for generating code snippets.

    Here’s a breakdown of the instruction message’s role:

    • Specifying the AI’s Role: The instruction message, with a role of “system,” explicitly defines the AI’s purpose within the code generation context. The message:
    • {
    • role: “system”,
    • content: “You are a code generator. You must answer only in markdown code snippets. Use code comments for explanations.”
    • }
    • informs the model that its primary function is to generate code, not engage in general conversation or provide information unrelated to coding tasks. [1]
    • Output Format Control: A crucial aspect of the instruction message is its directive regarding output format. The message instructs the AI to:
    • Provide responses exclusively in markdown code snippets. This ensures that the generated code is presented in a structured and readable format, suitable for direct use or easy integration into code editors.
    • Use code comments for explanations. This encourages the model to provide clarity and context for the generated code, making it more understandable for developers who might be using or adapting it. [1]
    • Demonstrating the Impact: The sources showcase the impact of the instruction message through a comparison of responses from the code generation and conversation models.
    • When asked “What is your purpose?,” the code generation model, primed with the instruction message, responds with a clear statement of its coding-centric role. [1]
    • In contrast, the conversation model, lacking the instruction message, provides a more general response, highlighting its broader purpose of assisting with information and tasks. [1]

    The inclusion of the instruction message is a strategic move to fine-tune the AI’s behavior. It transforms a general-purpose language model into a specialized code generation tool, ensuring that responses align with user expectations within the code generation context. This approach enhances the user experience, providing code snippets in a readily usable format and with helpful explanations embedded within the code itself.

    The Sentinel of Free Trials: Error Code 403 Guards the API Gate

    The sources provide a very detailed explanation of how the Genius application enforces limits on free tier usage, but they don’t explicitly specify an “error code” in the conventional sense. However, they do highlight the use of HTTP status code 403 (Forbidden) to signal that a user has exhausted their allotted free API calls.

    Here’s how this mechanism works within Genius:

    • Tracking API Usage: The application utilizes a database table called user_api_limits to keep track of each user’s API call count. This table stores the user’s ID and an integer representing the number of API calls they’ve made.
    • Enforcing the Limit: In each of the API routes (conversation, code, image, music, video), there’s logic that checks if the user is on a free trial and if they’ve exceeded the maximum allowed free calls (set to 5 in the provided code).
    • The 403 Response: If a free trial user attempts to make an API call beyond their limit, the server responds with a NextResponse object containing the message “Free trial has expired” and, crucially, an HTTP status code of 403.
    • Front-End Handling: On the front-end, the application specifically looks for this 403 status code to determine if the user needs to be prompted to upgrade to a paid subscription. If a 403 response is received, a modal window appears, encouraging the user to subscribe.

    Therefore, while not a traditional “error code” in the context of software exceptions or internal error handling, HTTP status code 403 serves as the signal that a user’s free trial has ended. This status code is a standard HTTP response indicating that the server understood the request but refuses to authorize it, fitting the scenario where a user has exceeded their free tier limits.

    The use of HTTP status codes in this way is a common practice in web applications to communicate the outcome of requests between the server and client.

    Taming Hydration Errors: A Strategic Approach in React

    While the sources do not directly address general strategies for resolving hydration errors in React, they do showcase a specific technique used to fix a hydration error within the Genius application’s MobileSidebar component. This technique, while not universally applicable to all hydration errors, offers valuable insights into how developers can approach these issues.

    Understanding the Root of the Problem

    Hydration errors occur when the HTML rendered on the server (during Server-Side Rendering or Static Site Generation) does not match the structure that React expects to find on the client-side during hydration. This mismatch can lead to unpredictable behavior and errors in the user interface.

    The MobileSidebar Case

    The specific hydration error encountered in the MobileSidebar component stemmed from the component’s initial rendering logic. The component relied on a state variable, isMounted, which was initially set to false. This meant that on the server, the component would render a different structure compared to the client, where isMounted would eventually become true.

    Solution: Conditional Rendering with isMounted

    To resolve this mismatch, the developers introduced a conditional rendering check within the MobileSidebar component. The code:

    if (!isMounted) return null;

    ensures that the component renders nothing (null) on the server, where isMounted is initially false. This aligns the server-rendered HTML with the initial state on the client, preventing the hydration error.

    Key Concept: Aligning Server and Client States

    The core principle behind this fix is to ensure that the initial state of the component on the server matches the state on the client during hydration. By conditionally rendering the component based on the isMounted state, the developers avoided the mismatch that was causing the hydration error.

    Beyond isMounted: Broader Considerations

    It’s important to note that while this technique worked effectively for the MobileSidebar component, it is not a one-size-fits-all solution for hydration errors. Resolving hydration errors often requires careful analysis to identify the root cause of the mismatch between the server and client.

    Some common causes of hydration errors and potential approaches to address them include:

    • Data Fetching: When data is fetched on the client-side after initial render, it can lead to changes in the component’s structure, causing a mismatch with the server-rendered HTML. Strategies include:
    • Fetching data on the server-side (if possible) and passing it as props to the component.
    • Using placeholder content or loading states until the data is fetched on the client.
    • Third-Party Libraries: Some third-party libraries may have side effects or rely on browser-specific APIs that are not available during server-side rendering. Solutions involve:
    • Initializing such libraries only on the client-side, using conditional logic.
    • Finding alternative libraries that are server-side rendering compatible.
    • Global State Management: If a component relies on global state that is not synchronized between the server and client, it can lead to hydration errors. Approaches include:
    • Initializing the global state on the server-side and passing it to the client.
    • Using server-side rendering compatible state management libraries or techniques.
    • DOM Manipulation: Direct manipulation of the DOM outside of React’s lifecycle methods can interfere with hydration. The recommendation is to:
    • Use React’s built-in mechanisms for DOM manipulation (e.g., refs).

    General Tips for Debugging Hydration Errors

    • Inspect the Error Message: React typically provides helpful error messages that pinpoint the location and potential cause of the hydration issue.
    • Console Logging: Strategically placing console.log statements within the component’s lifecycle methods can help track state changes and identify discrepancies between the server and client.
    • React Developer Tools: The React Developer Tools browser extension is invaluable for inspecting the component tree, props, and state, aiding in the identification of hydration mismatches.

    A Final Note

    Hydration errors can be tricky to debug, but with a systematic approach and a clear understanding of the potential causes, developers can effectively resolve these issues and ensure a smooth and consistent user experience. Remember that the key is to align the initial state of the component on the server with the state on the client.

    Guardian of the Premium Realm: The checkSubscription Function

    The checkSubscription function plays a crucial role in the Genius application, acting as the gatekeeper to premium features that are reserved for paid subscribers. Its purpose is to determine whether a user has an active and valid subscription, allowing or restricting access to certain functionalities based on this subscription status.

    Let’s break down the function’s logic and its implications within the application:

    • Retrieving User Subscription: The function begins by retrieving the user’s ID from the Clerk authentication system. If a user ID is found, it queries the database to fetch the user’s subscription details from the user_subscriptions table. This table stores information about a user’s subscription, including their Stripe customer ID, subscription ID, price ID, and the current subscription period end date.
    • Validating Subscription: The function then performs two crucial checks to validate the subscription:
    • Existence: First, it checks if a subscription record exists for the user. If no record is found, it implies the user is not subscribed, and the function returns false.
    • Validity: Second, if a subscription record is found, the function verifies its validity by checking if the current period end date, plus a one-day grace period, is greater than the current date. This grace period is a buffer to accommodate potential slight discrepancies in time calculations and provide a smoother user experience. If the subscription is expired, the function returns false.
    • Guiding Access Control: The boolean value returned by checkSubscription (true for active and valid subscriptions, false otherwise) is used throughout the application to control access to features. For example, in the API routes that handle AI generations (conversation, code, image, music, video), the checkSubscription function is called to determine whether to allow a user to proceed with their request or to trigger the “Upgrade to Genius Pro” modal.
    • UI Elements: The function also influences the display of UI elements. For instance, in the sidebar, the free generation counter is hidden if the user has an active subscription. Similarly, in the settings page, the subscription button’s text changes from “Upgrade” to “Manage Subscription” depending on the subscription status.

    Key Takeaway:

    The checkSubscription function serves as the central authority for managing subscription status within the Genius application. It encapsulates the logic for retrieving and validating a user’s subscription, providing a single source of truth that guides access control and UI adjustments based on subscription status. This approach promotes code modularity and ensures a consistent user experience, clearly differentiating between features available to free and paid users.

    Building Complete Links: The Role of the absoluteURL Function

    The absoluteURL function serves a critical purpose within the Genius application, particularly in the context of integrating with Stripe for subscription management. Its role is to generate complete, absolute URLs that are required by Stripe for seamless redirection and communication during the checkout and billing portal processes.

    Understanding the Need for Absolute URLs

    Stripe, as a third-party payment processing platform, interacts with your application through webhooks and redirects. For these interactions to function correctly, Stripe needs URLs that are fully qualified—meaning they include the protocol (e.g., https://), the domain name, and the path. This is in contrast to relative URLs, which only specify the path relative to the current page.

    Inside the absoluteURL Function

    The code for the absoluteURL function is simple yet effective:

    export function absoluteURL(path: string): string {

    return `${process.env.NEXT_PUBLIC_APP_URL}${path}`;

    }

    Let’s break down how it works:

    1. Retrieving the Base URL: The function first accesses an environment variable named NEXT_PUBLIC_APP_URL. This environment variable is expected to hold the base URL of the deployed application. For local development, this is typically set to http://localhost:3000. For a production deployment, it would be the actual domain name of your application (e.g., https://genius-app.com).
    2. Appending the Path: The function then takes the input path (which represents the relative path of the desired URL) and appends it to the base URL retrieved from the environment variable. The use of template literals (backticks) allows for easy string interpolation.

    Example Usage

    Let’s consider an example where you want to redirect the user to the settings page (/settings) after they complete the Stripe checkout process. Using the absoluteURL function, you would call it like this:

    const settingsURL = absoluteURL(‘/settings’);

    Assuming NEXT_PUBLIC_APP_URL is set to https://genius-app.com, the settingsURL variable would now contain the string “https://genius-app.com/settings&#8221;. This complete URL can then be passed to Stripe’s API during checkout session creation.

    Importance for Stripe Integration

    The use of the absoluteURL function is crucial for the following reasons:

    • Stripe Requirements: Stripe’s API, specifically for creating checkout sessions and billing portal sessions, mandates the use of absolute URLs for redirects. Relative URLs would not work, as Stripe needs to know the complete address to redirect to.
    • Environment Awareness: By relying on an environment variable for the base URL, the absoluteURL function adapts to different environments (development, staging, production) without requiring code modifications. This promotes maintainability and reduces the risk of errors when deploying to different environments.
    • Correct Redirection: Without using the absoluteURL function, Stripe might not be able to redirect the user back to your application correctly after completing a checkout or interacting with the billing portal. This would lead to a broken user experience and potentially lost subscriptions.

    In Summary:

    The absoluteURL function ensures that complete and correct URLs are used when interacting with Stripe, preventing redirection failures and enabling a smooth subscription management flow for Genius users. By abstracting the base URL into an environment variable, the function remains flexible and adaptable to different deployment scenarios.

    Styling Synergy: The Significance of the CN Library with Tailwind CSS

    The sources showcase a specific coding practice that highlights the synergy between Tailwind CSS and a utility library referred to as the CN library. While the sources don’t explicitly name the library, based on the provided code snippets and the context of Tailwind CSS usage, it is highly likely that the CN library refers to either the clsx library or the tailwind-merge library. Both libraries are popular choices within the Tailwind CSS ecosystem for enhancing class name management.

    Let’s break down the significance of using the CN library (assuming clsx or tailwind-merge) alongside Tailwind CSS:

    1. Streamlining Dynamic Class Names

    Tailwind CSS encourages the use of utility classes directly in your HTML markup. This approach leads to very readable and maintainable code, especially for static styles. However, when you need to apply styles dynamically based on conditions or component states, managing class names within HTML can become cumbersome.

    The CN library elegantly addresses this challenge. It provides a function that accepts an arbitrary number of arguments, each representing a potential class name. These arguments can be strings (for static Tailwind classes) or expressions that evaluate to either a string or false. The CN function intelligently merges these arguments, filtering out any falsy values, and returns a single, space-separated string of class names.

    2. Code Readability and Maintainability

    Imagine a scenario where you have a button component that needs to change its background color based on its state (e.g., active, disabled). Without a utility like CN, you might end up with conditional logic directly within your class name attribute, leading to lengthy and potentially hard-to-read markup:

    <button

    class={

    isActive ? ‘bg-blue-500 hover:bg-blue-700’ :

    isDisabled ? ‘bg-gray-300 cursor-not-allowed’ :

    ‘bg-blue-500 hover:bg-blue-700’

    }

    >

    Button

    </button>

    Using the CN library, this logic becomes significantly cleaner:

    import cn from ‘clsx’;

    <button

    class={cn(

    ‘bg-blue-500 hover:bg-blue-700’,

    isActive && ‘active-style’,

    isDisabled && ‘disabled-style’

    )}

    >

    Button

    </button>

    This approach separates the dynamic class logic from the static Tailwind classes, making the code more readable, maintainable, and easier to reason about.

    3. Avoiding Class Name Conflicts

    Tailwind CSS generates a vast number of utility classes. While this offers incredible flexibility, it also increases the potential for accidental class name collisions, especially when working with dynamic styles.

    The CN library helps mitigate this risk by providing a structured and predictable way to merge class names. It ensures that only valid class names are included in the final output, preventing unexpected behavior caused by conflicting styles.

    4. Optimizations (tailwind-merge)

    If the CN library specifically refers to tailwind-merge, there’s an additional layer of significance. tailwind-merge is built to optimize the final output of class names. It’s aware of the structure and hierarchy of Tailwind’s utility classes and intelligently merges them to minimize the resulting HTML size. This optimization can lead to performance improvements, particularly for larger applications.

    5. Integration with React Hook Form

    The sources demonstrate the use of the CN library within a React Hook Form setup. React Hook Form is a popular library for managing forms in React. It provides convenient ways to handle form state, validation, and submission. When combined with the CN library, it becomes straightforward to apply dynamic styles to form elements based on their validation status or other conditions managed by React Hook Form.

    Examples from the Sources

    The sources provide several instances where the CN library enhances class name management:

    • Sidebar Styling: In the sidebar.tsx component, the CN library is used to dynamically style the sidebar links based on the current route. This ensures that the active link is visually highlighted, providing clear navigation feedback to the user [1].
    • Heading Component: The heading.tsx component uses the CN library to apply styles to an icon container, merging static Tailwind classes with a dynamically determined background color [2].
    • Message Styling: When rendering messages, the CN library is used to differentiate the appearance of user messages and AI-generated messages [3].

    Conclusion

    The CN library, whether it’s clsx or tailwind-merge, proves to be a valuable asset when using Tailwind CSS. It streamlines dynamic class name management, improves code readability, helps avoid conflicts, and can potentially optimize the final output for better performance. Its integration with React Hook Form further enhances its utility for managing form element styles. By embracing these tools, developers can leverage the full power of Tailwind CSS while maintaining a clean and organized codebase.

    Prisma’s Role in Enforcing API Limits for Free Users

    The sources describe the development of an application with multiple AI-powered features, offering both free and paid tiers. The Prisma library is central to implementing API limits, ensuring free users can only access these features a limited number of times before needing to subscribe. Here’s a breakdown of its role:

    1. Defining the Limit Model:

    • In the schema.prisma file, a user_api_limit model is defined using Prisma’s schema definition language. [1]
    • This model includes fields to track the user ID (user_id), the number of times they’ve used the API (count), and timestamps for creation and updates (created_at and updated_at). [1]
    • This schema acts as the blueprint for a table in the PlanetScale database, which Prisma will manage. [2]

    2. Tracking API Usage:

    • Whenever a free user successfully uses an AI feature, the increase_api_limit function is invoked. [3, 4]
    • This function uses Prisma Client (Prisma_db) to interact with the database. It first checks if a user_api_limit record exists for the user. [5]
    • If a record exists, the count field is incremented using an update operation. [5]
    • If no record is found, a new one is created with a count of 1, indicating the user’s first API call. [5]

    3. Enforcing the Limit:

    • Before each API call, the check_api_limit function is called to determine if the user has exceeded their free usage. [4]
    • This function fetches the user’s user_api_limit record using Prisma_db. [4]
    • It compares the count with a predefined max_free_counts constant (set to 5 in the example). [3, 4]
    • If the count is less than the limit, the function returns true, allowing the API call. [4]
    • If the limit is reached, the function returns false. The API route then responds with a 403 error (“free trial has expired”), triggering the “Upgrade to Genius Pro” modal on the front end. [4, 6]

    4. Visualizing Usage in Prisma Studio:

    • The sources mention using npx prisma studio to launch Prisma Studio, a visual interface for interacting with the database. [1, 4]
    • This tool allows developers to view and manipulate data, including the user_api_limit records, providing a way to monitor free user usage. [1, 4]

    In essence, Prisma acts as the bridge between the application logic and the database:

    • It provides a convenient way to define the data model for tracking API usage.
    • Its client library (Prisma_db) offers functions to query, update, and create records, abstracting away complex database interactions.
    • This enables efficient tracking of free user API calls and enforcement of limits, guiding users to subscribe for unlimited access.

    Capturing and Processing User Input for Code Generation

    The sources provide a detailed walkthrough of building a code generation tool within a larger AI application. Let’s examine the method used to handle user input in this specific implementation:

    1. The Input Form:

    • The user interface for code generation features a text input field, allowing users to provide a description of the code they wish to generate.
    • The input field is managed using the react-hook-form library, which provides structure and validation capabilities.

    2. Schema Validation:

    • A schema is defined using the zod library to ensure the user input conforms to the expected format.
    • In the provided example, the schema specifies that the input (named “prompt”) must be a string with a minimum length of one character.
    • This validation step helps prevent errors and ensures the input is suitable for processing by the code generation model.

    3. Submission Handling:

    • When the user submits the form, the onSubmit function, defined within the code page component, is triggered.
    • The onSubmit function receives the validated input values from react-hook-form.

    4. Preparing the API Request:

    • The input prompt is packaged into a request object to be sent to an API route responsible for code generation.
    • This route, located at /api/code, handles the interaction with the underlying code generation model, which is powered by OpenAI.

    5. Sending the Request:

    • The request object is sent to the /api/code route using an HTTP request, likely facilitated by the axios library, a popular choice for making API calls in JavaScript applications.

    6. Server-Side Processing:

    • The /api/code route receives the request and extracts the user’s prompt.
    • The prompt, along with a pre-defined instruction message, is sent to the OpenAI API to generate the code.
    • The instruction message guides the OpenAI model, specifying that it should act as a “code generator” and provide responses in the form of markdown code snippets with comments for explanations.

    7. Response Handling:

    • The code generated by the OpenAI model is returned to the client-side application as part of the API response.

    8. Displaying the Generated Code:

    • The client-side application receives the code snippet and displays it to the user.
    • The react-markdown library is used to render the markdown content, ensuring proper formatting of the code and comments.
    • Additional styling is applied using Tailwind CSS classes to enhance the visual presentation of the code.

    In summary, the method for handling user input for code generation involves:

    • Collecting Input: Using a form with react-hook-form for structure and validation.
    • API Communication: Sending the input to an API route for processing by the code generation model (OpenAI).
    • Code Display: Rendering the generated code using react-markdown and applying styles with Tailwind CSS.

    This process effectively bridges the gap between user intent and AI-powered code generation, providing a user-friendly interface and a structured backend to produce code snippets based on natural language descriptions.

    Managing the Loading State during Code Generation

    The sources provide a detailed illustration of how loading states are managed during code generation requests, ensuring a smooth user experience while the application interacts with the OpenAI API. Here’s a comprehensive explanation based on the source code and our previous conversation:

    1. Initializing the Loading State:

    • In the code page component (likely named code.tsx), a state variable isLoading is introduced using the useState hook from React. It’s initialized to false, indicating that no code generation request is in progress.

    2. Triggering the Loading State:

    • When the user submits the code generation request, the onSubmit function is invoked. Inside the try block of this function, the setLoading function (paired with the isLoading state) is called with true to signal the start of the code generation process.

    3. Displaying a Loading Indicator:

    • A conditional rendering mechanism is implemented to display a loading indicator while isLoading is true.
    • This indicator could be a simple text message (“Genius is thinking…”) or a more visually engaging animation. The sources showcase the creation of a Loader component, which is likely used for this purpose.

    4. Sending the API Request:

    • While the loading indicator is visible, the application concurrently sends the code generation request to the /api/code route. This is an asynchronous operation, allowing the user interface to remain responsive and provide feedback to the user.

    5. Handling the Response:

    • Once the /api/code route completes the interaction with the OpenAI API and returns a response, the onSubmit function’s try block continues execution.

    6. Resetting the Loading State:

    • Inside a finally block within the onSubmit function, the setLoading function is called with false to reset the loading state, regardless of whether the code generation was successful or encountered an error. This ensures that the loading indicator is hidden and the user interface returns to its normal state.

    7. Displaying the Result or Error:

    • Based on the response from the /api/code route, the application either displays the generated code snippet or handles any errors that occurred during the process. This might involve showing an error message to the user or initiating other appropriate actions.

    Code Snippet Illustration:

    const [isLoading, setLoading] = useState(false);

    const onSubmit = async (values) => {

    try {

    setLoading(true); // Start loading

    const response = await axios.post(‘/api/code’, values);

    // … handle response, display code snippet

    } catch (error) {

    // … handle error

    } finally {

    setLoading(false); // Stop loading

    }

    };

    Key Takeaways:

    • The loading state management is crucial for providing a seamless user experience during asynchronous operations like code generation.
    • The use of useState and conditional rendering allows the application to dynamically display a loading indicator while the request is being processed.
    • The finally block ensures that the loading state is always reset, preventing the indicator from getting stuck in the loading state if an error occurs.

    Distinguishing User and AI Messages in the UI

    The sources offer a detailed guide to constructing a conversational AI application. While they don’t explicitly detail the styling of user versus AI messages, they provide enough clues to infer a potential approach:

    1. Message Structure:

    • The conversation history is stored in a messages array, where each message is an object with properties like role (either “user” or “assistant”) and content.

    2. Dynamic Styling with CN:

    • The sources demonstrate using a utility function CN (likely a custom wrapper around the classnames library) to dynamically apply Tailwind CSS classes based on conditions.

    3. Background Color Differentiation:

    • Based on the code snippet for styling messages, it can be inferred that user messages are given a white background (bg-white) with a subtle border, while AI (assistant) messages have a muted background (bg-muted).

    4. Potential Additional Styling:

    • While not explicitly mentioned, it’s common to further differentiate user and AI messages visually. Possibilities include:
    • Text alignment: Aligning user messages to the right and AI messages to the left.
    • Avatar icons: Displaying distinct avatars next to each message type, as hinted at by the creation of userAvatar and botAvatar components.
    • Font variations: Subtle differences in font weight or style could be applied.

    Code Snippet Illustrating the Approach:

    messages.map((message) => (

    <div

    key={message.content}

    className={CN(

    “p-8 w-full flex items-start gap-x-8 rounded-lg”,

    {

    “bg-white border border-black/10”: message.role === “user”,

    “bg-muted”: message.role !== “user”,

    }

    )}

    >

    {/* Avatar Icon */}

    {message.role === “user” ? <UserAvatar /> : <BotAvatar />}

    {/* Message Content */}

    <p className=”text-sm”>{message.content}</p>

    </div>

    ));

    Inferred Visual Distinction:

    Based on the available information, it’s likely that user messages appear with a white background and a border, while AI messages have a muted background. Additional visual distinctions, like text alignment or avatar icons, are not explicitly described but are common practices in chat interfaces and hinted at in the source code.

    Highlighting the Active Page in the Sidebar Navigation

    The sources provide a step-by-step guide on constructing an AI application with a sidebar navigation menu. They demonstrate a clear method for dynamically applying a class name to the active page’s link to visually highlight it.

    1. Identifying the Current Route:

    • Within the sidebar.tsx component, the usePathname hook from the next/navigation library is used to determine the current route (URL path) of the application.
    • This hook returns a string representing the pathname, which is then stored in the pathname constant.

    2. Route Configuration:

    • An array named routes stores the configuration for each sidebar link.
    • Each object in the routes array contains properties such as label, icon, href (the target URL), and color (for styling the icon).

    3. Mapping Routes to Links:

    • The routes array is iterated over using the map function to generate the link elements for the sidebar navigation.

    4. Conditional Class Application with CN:

    • The CN utility function (likely based on classnames) is employed to dynamically apply Tailwind CSS classes based on a condition.

    5. The Highlighting Condition:

    • For each link, the CN function evaluates whether the pathname (current route) matches the href property of the current route object from the routes array.
    • If the paths match, indicating the link represents the active page, the CN function applies the classes text-white and bg-white/10 to give the link a highlighted appearance (white text with a semi-transparent white background).
    • If the paths don’t match, the link is styled with a less prominent gray color (text-zinc-400).

    Code Snippet Illustrating the Technique:

    const pathname = usePathname();

    // …

    routes.map((route) => (

    <Link key={route.href} href={route.href}>

    <div

    className={CN(

    // Default classes

    “text-sm group flex padding-3 w-full justify-start font-medium cursor-pointer hover:text-white hover:bg-white/10 rounded-lg transition”,

    // Conditional class for active link

    pathname === route.href ? “text-white bg-white/10” : “text-zinc-400”

    )}

    >

    {/* Icon and Label rendering */}

    </div>

    </Link>

    ));

    In Conclusion:

    This method effectively leverages the usePathname hook, the CN utility function, and conditional logic to dynamically style the active sidebar link based on the current route, providing a clear visual indication of the user’s location within the application.

    Strategies to Prevent Server-Side Rendering and Hydration Mismatches

    The sources primarily focus on building an AI SaaS application using Next.js, OpenAI, and other technologies. While they don’t explicitly detail comprehensive strategies for preventing all server-side rendering (SSR) and hydration errors, they do showcase specific techniques and offer insights into potential causes and solutions for these issues.

    1. Understanding the Challenge

    Hydration in Next.js involves the process of “attaching” JavaScript behavior to the server-rendered HTML. Mismatches occur when the client-side JavaScript generates a different DOM structure or state than what was initially rendered on the server. This can lead to unexpected behavior, visual inconsistencies, and even application errors.

    2. Techniques Employed in the Sources

    a) Using useEffect for Client-Side Initialization:

    • In components like FreeCounter, the sources demonstrate the use of React’s useEffect hook to perform actions only after the component has mounted in the browser. This prevents code that relies on browser APIs (like window or document) from running on the server, where those APIs are not available.

    // FreeCounter.tsx (simplified)

    ‘use client’;

    export const FreeCounter = ({ apiLimitCount }) => {

    const [mounted, setMounted] = useState(false);

    useEffect(() => {

    setMounted(true);

    }, []);

    if (!mounted) return null; // Avoid rendering on the server

    // … rest of the component logic

    };

    b) The use client Directive:

    • The sources consistently use the ‘use client’ directive at the top of client-side components. This explicitly instructs Next.js to treat these components as client-only, preventing them from being rendered on the server. This is crucial for components that rely on browser-specific functionality or interact with the DOM in ways that could lead to hydration mismatches.

    c) Conditional Rendering with isMounted State:

    • Components like FreeCounter use a state variable (isMounted) to track whether the component has mounted in the browser. By conditionally rendering content based on this state, they ensure that server-side rendering produces a minimal, non-interactive version of the component, preventing potential hydration errors caused by client-side logic executing prematurely.

    3. Potential Areas for Improvement

    The sources, while demonstrating good practices, could be enhanced with a more comprehensive error-handling strategy and explicit checks for potential hydration mismatches. Here are some areas to consider:

    a) Robust Error Handling:

    • Implementing more robust error handling within try…catch blocks can help catch and gracefully handle unexpected situations during rendering. For example, catching errors related to API requests or component lifecycles can prevent the application from crashing due to unexpected data or states.

    b) Hydration Mismatch Detection and Resolution:

    • While not explicitly covered in the sources, Next.js offers tools and techniques to detect and resolve hydration mismatches:
    • react-hydration-error-boundary: This library can help capture and handle hydration errors, providing insights into their causes and enabling graceful recovery.
    • Data Fetching Strategies: Carefully choosing and implementing data fetching strategies (e.g., getServerSideProps, getStaticProps) can ensure that the data used for rendering is consistent between the server and client.
    • Unit and Integration Testing: Writing tests to verify that components render consistently on both the server and client can help identify and prevent hydration issues early in the development process.

    4. Additional Considerations (Not from Sources)

    Third-Party Libraries: Be mindful of how third-party libraries handle SSR. Some libraries might not be SSR-compatible or might require specific configuration to work correctly in a Next.js environment. Always consult the library’s documentation for guidance.

    State Management: If your application uses complex state management, ensure that your state is initialized and synchronized correctly on both the server and client. Mismatches in initial state can easily lead to hydration errors.

    In Summary

    Preventing SSR and hydration errors requires a combination of careful planning, coding practices, and leveraging Next.js’s features and tools. While the sources provide valuable examples, they could be further strengthened with more comprehensive error handling and explicit hydration mismatch detection strategies.

    Here’s a bibliography for building a SaaS AI platform using Next.js 13, React, Tailwind CSS, Prisma, and Stripe:

    Books

    1. Holt, J. (2022). Building Scalable SaaS Applications with Next.js: A Guide to High-Performance, Modular Web Applications. Packt Publishing.
    • This book covers advanced topics on creating SaaS applications with a focus on performance optimization, modular architecture, and deploying with Next.js.
    1. Grider, S. (2023). Mastering React and TypeScript: Build Modern Full-Stack Applications. Independently published.
    • A detailed guide on combining React and TypeScript to build reliable, modern front-end applications, especially useful for Next.js users looking to build scalable SaaS products.
    1. Bell, A. (2023). Full Stack with Prisma: Database-Driven Web Applications for Developers. O’Reilly Media.
    • An in-depth resource on using Prisma ORM to handle data in full-stack applications, covering setup, database relationships, and optimization.
    1. Carlson, T. (2022). Mastering Tailwind CSS: Styling Modern Web Applications with Ease. Manning Publications.
    • A focused guide on using Tailwind CSS for design systems in modern web applications, ideal for creating clean, responsive UIs in SaaS platforms.

    Articles and Blog Posts

    1. Next.js Blog (2023). “What’s New in Next.js 13: Turbocharged Performance and API Routes.” Retrieved from https://nextjs.org/blog
    • Official Next.js blog explaining the latest features in Next.js 13 that are particularly useful for SaaS development, including server components, routing, and performance improvements.
    1. Stripe Docs. (2023). “Setting Up Stripe for SaaS Billing.” Retrieved from https://stripe.com/docs
    • Stripe documentation with sections specifically addressing SaaS billing, including customer management, subscriptions, and usage-based billing.
    1. Lee Robinson. (2023). “Creating a SaaS with Next.js, Prisma, and Stripe.” Vercel Blog. Retrieved from https://vercel.com/blog
    • A comprehensive guide on integrating Prisma and Stripe with Next.js, featuring a sample application and practical tips for SaaS billing.
    1. Dev.to (2023). “How to Integrate Prisma and Next.js for Data-Driven Apps.” Retrieved from https://dev.to
    • Step-by-step tutorial on setting up Prisma with Next.js for database management, with an emphasis on SaaS product scenarios.

    Documentation

    1. Next.js Documentation (2023). Next.js 13 Documentation. Retrieved from https://nextjs.org/docs
    • Official Next.js documentation for the latest version, which includes information on server components, API routes, and deployment tips for SaaS applications.
    1. Tailwind CSS Documentation (2023). Tailwind CSS Documentation. Retrieved from https://tailwindcss.com/docs
    • The Tailwind CSS official docs provide everything you need to build responsive UIs, including customizations and component-based styling best practices for SaaS applications.
    1. Prisma Documentation (2023). Prisma Documentation. Retrieved from https://www.prisma.io/docs
    • Comprehensive resource on Prisma, including ORM setup, schema modeling, and advanced query functions tailored for full-stack SaaS applications.
    1. Stripe API Documentation (2023). Stripe API Documentation. Retrieved from https://stripe.com/docs/api
    • Essential documentation for implementing Stripe API features for payments, subscriptions, and webhook integrations in SaaS platforms.

    Video Courses

    1. Udemy. (2023). “Build and Scale a SaaS Product with Next.js, Prisma & Stripe.” Retrieved from https://www.udemy.com
    • Covers the end-to-end process of building and scaling a SaaS product, with a focus on integrating Stripe for billing and Prisma for data management.
    1. Frontend Masters. (2023). “Advanced Next.js 13 and SaaS Application Development.” Retrieved from https://frontendmasters.com
    • Focuses on the new features in Next.js 13, along with practical lessons on using Tailwind, React, and Prisma for developing SaaS platforms.
    1. YouTube – Fireship. (2023). “Next.js 13 Crash Course – Build a Full-Stack SaaS.” Retrieved from https://youtube.com/fireship
    • A quick but in-depth look at the essentials for building a full-stack SaaS with Next.js 13, covering Prisma, Tailwind, and Stripe integration.

    These resources offer a solid foundation for building a SaaS AI platform, covering front-end and back-end development, payment processing, and styling. Let me know if you’d like more specific tutorials or if you have questions about a particular topic!

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Full-Stack App: Building a Reminder Application with React Native

    Full-Stack App: Building a Reminder Application with React Native

    The provided text meticulously documents the creation of a full-stack reminder application. It begins by outlining database schema migrations for “users” and “reminders,” followed by establishing API routes with corresponding controller functions. The explanation details the implementation of a service layer to handle business logic and interact with data models, incorporating input validation using Zod middleware and robust error handling. Finally, the text guides the development of a React Native frontend, demonstrating data fetching with TanStack Query, component creation, state management, and the implementation of CRUD operations for reminders, culminating in a functional mobile application.

    React Native Development Fundamentals Study Guide

    Quiz

    1. What is the primary benefit of using a step-by-step guide during a coding tutorial?
    2. Explain the role of NodeJS in React Native development.
    3. What is the purpose of npm init in a project setup?
    4. Describe the function of the Express framework in the context of backend development.
    5. Why is it considered insecure to hardcode sensitive information like API keys directly in your application code?
    6. What is an environment variable, and how is it typically used in a NodeJS application?
    7. Explain the concept of database migrations and why they are important for managing database schemas.
    8. What is the key difference between raw SQL queries and using an Object-Relational Mapper (ORM) for database interactions?
    9. In the Model-View-Controller (MVC) plus Service pattern, what is the responsibility of the service layer?
    10. What is a middleware in Express, and what is its typical use case in handling requests?

    Quiz Answer Key

    1. A step-by-step guide provides a structured and predictable path for learners to follow, ensuring they don’t miss crucial steps and can replicate the instructor’s actions more easily. It also serves as a reference point for troubleshooting and review.
    2. NodeJS is a JavaScript runtime environment that allows developers to execute JavaScript code outside of a web browser. In React Native development, it is essential for running the Metro bundler, which compiles and packages the JavaScript code for deployment on mobile devices.
    3. npm init is a command used to initialize a new Node Package Manager (npm) project. It creates a package.json file, which keeps track of project dependencies, scripts, name, version, and other metadata.
    4. Express is a minimal and flexible Node.js web application framework that provides a robust set of features for building web and mobile applications. It simplifies tasks such as routing, middleware integration, and handling HTTP requests and responses.
    5. Hardcoding sensitive information directly in the code exposes it to potential security breaches if the code repository is compromised or accessed by unauthorized individuals. Environment variables offer a more secure way to manage configuration by keeping sensitive data separate from the codebase.
    6. An environment variable is a dynamic named value that can affect the way running processes will behave on a computer. In NodeJS applications, they are commonly used to store configuration settings like port numbers and database URLs, keeping them separate from the main codebase for security and flexibility.
    7. Database migrations are version-controlled changes to a database schema. They are important because they provide a structured way to evolve the database over time, ensuring consistency across different environments (development, staging, production) and allowing for easy rollback of changes if necessary.
    8. Raw SQL queries involve writing SQL statements directly to interact with the database, offering fine-grained control and potentially better performance for complex queries. ORMs provide an abstraction layer, allowing developers to interact with the database using object-oriented code, which can improve readability and development speed for common operations.
    9. In the MVC plus Service pattern, the service layer contains the core business logic of the application. It receives requests from the controller, processes data (often interacting with models), and performs operations before returning a response back to the controller. It separates concerns and promotes reusability.
    10. A middleware in Express is a function that has access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. Middleware functions can perform tasks such as request parsing, authentication, logging, and error handling before or after the main route handler.

    Essay Format Questions

    1. Discuss the benefits and drawbacks of using raw SQL versus an ORM for database interactions in a web application development project. Consider factors such as performance, development speed, maintainability, and team expertise.
    2. Explain the significance of implementing the Model-View-Controller (MVC) plus Service pattern in backend development. How does this architectural approach contribute to code organization, maintainability, and scalability of an application?
    3. Describe the role and importance of middleware in the Express framework. Provide examples of common middleware use cases, such as request parsing, authentication, and error handling, and explain how they enhance the functionality and structure of a web application.
    4. Outline the process of setting up a basic NodeJS backend for a React Native application, including initializing the project, installing necessary dependencies like Express, and configuring environment variables. Emphasize the best practices for managing project configuration and security.
    5. Discuss the fundamental concepts of React Native navigation using a library like Expo Router. Explain how to define routes, navigate between screens, and manage layouts to create a user-friendly mobile application experience.

    Glossary of Key Terms

    • API (Application Programming Interface): A set of rules and protocols that allows different software applications to communicate and exchange data with each other.
    • Backend: The server-side of a web or mobile application, responsible for handling data storage, business logic, and API endpoints.
    • Dependency: An external library or package that a software project relies on to function correctly.
    • Endpoint: A specific URL that represents a resource or functionality exposed by an API.
    • Frontend: The client-side of a web or mobile application, responsible for the user interface and user experience.
    • HTTP (Hypertext Transfer Protocol): The foundation of data communication for the World Wide Web, used for transmitting requests and responses between clients and servers.
    • JSON (JavaScript Object Notation): A lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate.
    • Middleware: Functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle in Express.
    • Module: A self-contained unit of code that can be imported and used in other parts of a program.
    • npm (Node Package Manager): The default package manager for the JavaScript runtime environment Node.js.
    • React Native: A JavaScript framework for building native mobile applications for iOS and Android.
    • REST (Representational State Transfer): An architectural style for designing networked applications, relying on stateless servers and standard HTTP methods.
    • Route: A defined path in a web application that maps a specific URL to a particular handler function.
    • Schema: A blueprint or structure that defines the format and types of data.
    • Server: A computer or software that provides services or resources to other computers (clients) in a network.
    • State (in React): Data that can change over time and affects the behavior and rendering of a component. When state changes, the component re-renders.
    • UI (User Interface): The means by which a user interacts with a computer system or software application.
    • URL (Uniform Resource Locator): A web address that specifies where a resource is located on the internet and the protocol used to access it.

    Briefing Document: React Native Full Course – Backend and Frontend Development

    Document Date: October 27, 2024

    Sources: Excerpts from “01.pdf”

    Overview:

    This document summarizes the main themes and important ideas presented in the provided excerpts from a resource intended to guide users through building a functional React Native application with a backend API. The content covers setting up a NodeJS backend with Express, database integration using PostgreSQL via Neon, basic API endpoint creation, structuring the application with MVC+Service pattern, data validation using Zod, error handling, and the initial setup of a React Native frontend using Expo Router and Tailwind CSS.

    Part 1: NodeJS Backend Setup and Fundamentals

    Main Themes:

    • Hands-on Learning: The core philosophy is learning by doing, emphasizing practical coding experience to build a functional application.
    • Structured Course: The presenter introduces a comprehensive React Native course developed by Vadim, highlighting its detailed guides, videos, and educational exercises.
    • Step-by-Step Guidance: A downloadable step-by-step guide is provided, which will be used throughout the tutorial. This guide will be updated based on user feedback.
    • Backend with NodeJS and Express: The tutorial starts with setting up a NodeJS project and using the Express framework to build the backend API.
    • Basic API Endpoint: The initial setup involves creating a simple “Hello World” API endpoint to demonstrate the fundamentals of routing and server responses.
    • Environment Variables: The importance of using .env files for configuration, especially for sensitive information like port numbers and API keys, is emphasized.
    • Nodemon for Development: The use of nodemon (implied through the –watch flag in the npm run dev script) for automatic server restarts on code changes is introduced.
    • API Testing with Insomnia: The presenter recommends and demonstrates the use of Insomnia (or similar tools like Postman or Bruno) to test API endpoints.

    Key Ideas and Facts:

    • The course aims to take users from writing their own code to having a functional app they can showcase.
    • “everything ties together and um yeah witnessing that by writing your your own code and then again at the end you will walk away with a functional app that you can uh show to whoever you want and say yeah this is what I’ve built”
    • The presenter is a software developer with several years of experience, a former startup CTO, and a former university instructor in software engineering.
    • “I am a software developer i have quite a few years experience in this field and I am already only like let’s say six plus years u startup CTO and co-owner um then I was also former and university instructor in software engineering”
    • A detailed React Native course with workshops is available for enrollment.
    • “it has everything that you need to know about React Native completely everything in very very much detail with the huge guides and videos so if you are considering if you are looking for a well ststructured course in React Native I highly suggest you to check it out”
    • A step-by-step guide for the tutorial can be downloaded after providing a name and email.
    • “after clicking on this link you’ll need to provide your name and an email and we’ll send this guide that I will show you in a second uh to your email address so then you can reuse it anytime you want”
    • NodeJS is a JavaScript runtime that allows executing JavaScript outside of the browser.
    • “as I mentioned already in the presentation NodeJS is a JavaScript runtime that allows ows us to execute basically JavaScript outside of the browser”
    • npm init is used to initialize a new NodeJS project, and npm install <package-name> is used to install dependencies like Express.
    • “just run npm in it and that’s it”
    • “now that we installed it we need to uh run mpm install express”
    • ES6 modules can be enabled by adding “type”: “module” to package.json, allowing the use of import instead of require.
    • “we will be enabling uh the EA6 uh modules which is in my opinion very neat it’s going to make the code a bit more readable and uh let’s say more modern uh so to do that we simply need to pass the type module in our package.json”
    • Environment variables, stored in a .env file, are accessed using process.env.<VARIABLE_NAME> and should be protected from being committed to version control.
    • “hard-coding configuration values like port numbers is quite bad and especially uh hard coding and inside not in the environment file but uh adding let’s say somewhere here inside the application your API keys is horribly bad because it’s very insecure are instead we use environment variables for that basically uh env file”
    • The npm run <script-name> command executes scripts defined in the scripts section of package.json, allowing for shorter commands like npm run dev to start the server with specific configurations (e.g., using .env file and watching for changes).
    • “if I run to run our server the only thing I need to do is say npm run and then specify the name of this script”
    • .gitignore file specifies files and folders that should not be committed to Git, such as node_modules and .env.
    • “in this file we specify which uh files or folders from our um from our application we do not want to push to versioning control and usually these are the files that we can configure easily ourselves or very let’s say uh private files like environment so one example would be node modules”
    • API testing tools like Insomnia are used to verify that API endpoints work as expected.
    • “there’s many different API to testing tools like one of the most important ones is probably a postman uh now in the recent times it’s getting like they have a lot of functionalities it’s kind of over complicated ated at this point uh to start with but you might see it quite often also insomnia is very popular one”

    Part 2: Database Integration with PostgreSQL and Neon

    Main Themes:

    • Database Necessity: A database is essential for persisting and managing application data.
    • Serverless PostgreSQL with Neon: The tutorial opts for a serverless PostgreSQL database hosted on Neon due to its popularity and suitability.
    • Database Types Overview: A brief overview of self-hosted, managed, and serverless database options is provided.
    • Raw SQL vs. ORM: The tutorial chooses to use raw SQL queries for database interactions, emphasizing the importance of understanding SQL. While ORMs (like Drizzle or Prisma) offer benefits, raw SQL provides a better foundation.
    • node-postgres Library: The pg library (node-postgres) is used to execute SQL queries and manage database connections in NodeJS.
    • Database Connection Configuration: Database connection details are stored as an environment variable (DATABASE_URL) for security.
    • Connection Pooling: The pg library supports connection pooling, which is beneficial for performance.
    • Database Migrations: Migrations are introduced as a way to manage changes to the database schema in a version-controlled and structured manner. The tutorial manually simulates migrations by creating SQL files with timestamped names.

    Key Ideas and Facts:

    • Neon is a serverless PostgreSQL database used in the tutorial.
    • “for this project right away I’m saying like we will use a serverless database uh posgrade SQL as well and we’re using posgrade SQL because it’s probably the most popular I would say and it’s very good so yeah that’s that but let’s really uh quickly cover all of the t like not all but main types that you might encounter of databases”
    • Raw SQL queries are favored for this learning project to ensure a strong understanding of database interactions.
    • “today we will be using raw SQLs because well this is a learning project and I believe and I I would argue like very harshly that it is a lot better to understand SQL and it’s a lot more valuable to learn that uh than simply relying on an RM”
    • The pg library (npm install pg) is used for interacting with the PostgreSQL database.
    • “in order to uh like write these uh SQL queries we need a library for that and we will use um install pg uh I mean pg which basically stands for posgress and this is the most commonly library it’s called node posgress”
    • Database connection string from Neon is stored in the .env file as DATABASE_URL.
    • “we will need to add this connection like this so we will say uh we are creating a new uh environment variable called database URL”
    • Migrations involve up functions to apply schema changes and down functions to revert them.
    • “here we are creating two different functions one is going to be down called down and the other one is going to be called up and this usually means we are migrating up and or we are migrating down”
    • The example migration creates a users table with id, name, and created_at fields.
    • “in the up we are what we’re trying to do is creating a new table in our database so what we’re doing here we’re saying okay create table basically create a new table if it doesn’t exist yet because if it will exist it will not create and the name of the table the is called users”
    • Another migration creates a reminders table with fields like id, reminder (text, not null), notes (text, nullable), completed (boolean, default false), and user_id (integer, foreign key referencing users table).
    • “now we need to do the same for reminders and now we can try to write this uh reminders code or like migration ourselves so first of all what are we doing we’re importing the database from and we will say okay so let’s import it from config and database and adds very important unless it’s got otherwise it’s going to throw an error for you okay now that we imported we have two functions well one of them is called uh up”
    • Foreign key constraints ensure data integrity by linking records between tables (e.g., reminders.user_id referencing users.id).
    • “we will add a user ID which is going to be an integer and it’s also very important to say that it will reference the users table and the ID field of that table and it’s also very important to say on delete cascade we’ll talk about it in a second but it means that if the user is deleted all of his or her reminders will be deleted as well”

    Part 3: Building the API Endpoints and Structuring the Backend

    Main Themes:

    • CRUD Operations: The tutorial focuses on implementing Create, Read, Update, and Delete (CRUD) operations for the reminders resource.
    • API Endpoint Design: Standard HTTP methods (GET, POST, PATCH, DELETE) are used for different actions on the /reminders resource. Endpoints for getting all, getting by ID, creating, updating, and deleting reminders are defined.
    • Route Separation: To improve maintainability, routes are separated into individual files (e.g., remindersRoutes.js) within a routes folder.
    • MVC+Service Architectural Pattern: The backend is structured using the Model-View-Controller (MVC) pattern with an additional Service layer. This promotes separation of concerns.
    • Models: Handle database interactions (executing SQL queries).
    • Services: Contain business logic and data processing, interacting with models.
    • Controllers: Handle incoming requests, call service methods, and send responses back to the client.
    • Middleware: Express middleware functions are used to perform tasks before reaching route handlers, such as parsing JSON request bodies.

    Key Ideas and Facts:

    • API endpoints are defined using Express router.
    • “we will need to import router but also from express and router is what allows us to create these separated routes very nicely”
    • The app.use(‘/reminders’, remindersRoutes) mounts all routes defined in remindersRoutes under the /reminders path.
    • “now we can say that router dot slash uh without saying this reminders part router slash id then once again like this and like this so now it’s not yet finished we need to have one last adjustment so now if we go to our index file and inside here at the top we’ll import these routes so it’s called reminder routes and we are importing them from and they’re imported from actually it’s only one routes reminder routes.js”
    • The MVC+Service pattern enhances code organization and maintainability.
    • “to solve this issue we will be creating a new folder called routes and this folder will keep all of our routes separated so for example we have reminders routes so we will say reminders routes.js you can have let’s say user routes.js and you can even like have as many as you need and it will keep everything very clean and structured”
    • Controllers receive requests, extract data, call service methods, and send responses.
    • “the controller will handle these requests and send back the responses to the user well you can right away understand that it’s kind of like a waiter in a restaurant so it’s the one that will take the order from the user which is a request it will pass this order to the kitchen to basically create whatever was ordered which the kitchen is in our analogy a service layer and it brings back the prepared dish which is going to be the response to the user”
    • Services contain the core business logic and interact with the database through models. They can also perform data sanitization and other processing.
    • “this service layer which is as I said is kind of like a kitchen inside a restaurant which is responsible for the logic and the actual processing of the data so the kitchen the service layer takes the order from the controller a waiter and processes it prepares the food based on the ingredients a model”
    • Models are responsible for executing database queries.
    • “there is models layer which only communicates with a database uh in our like code example but in a kitchen example you can think of model like an ingredientre different ingredients to make those dishes”
    • express.json() middleware is used to parse incoming request bodies as JSON.
    • “express doesn’t parse the incoming data to JSON by default so we need to enable that by like basically passing the the middleware and the middleware ware it’s also um yeah let’s say what is let’s talk about what is middleware in general middleware is kind of a helper functions that help you process the requests before they reach the routes”
    • Example model functions for reminders include getAll, findById, create, update, and delete. These functions execute raw SQL queries.
    • “let’s create our first model which is going to be called reminders model.js and in here we will import our database connection and then we will start defining our functions”
    • Service functions call the corresponding model functions and can include additional business logic (e.g., data sanitization).
    • “in here we can import the model uh in here we just go import yes reminder model and also don’t forget to add.js and now let’s start using them well first of all the yeah the first one is going to be very easy we don’t need to pass anything we don’t need to do anything it’s simply return reminder model get all and we get all of these uh reminders and return them right away”

    Part 4: Data Validation with Zod

    Main Themes:

    • Data Validation Importance: Validating incoming data is crucial for ensuring data integrity and preventing errors.
    • Zod Library: The Zod library is introduced as a schema declaration and validation library for TypeScript.
    • Schema Definition: Zod schemas are defined to specify the expected structure and types of data for reminders (e.g., reminder, notes, completed, user_id). Separate schemas are created for creating and updating reminders to reflect different validation requirements.
    • Validation Middleware: A custom Express middleware is created to use the defined Zod schemas to validate incoming request bodies. This middleware checks if the data conforms to the schema and returns appropriate error responses if validation fails.

    Key Ideas and Facts:

    • Zod allows defining schemas as TypeScript types with runtime validation.
    • “for this we will use a very popular library called zod so let’s install it by running npm install zod”
    • Schemas define the expected data structure, types, and constraints (e.g., required fields, string lengths).
    • “what we are saying here is that we are expecting an object and this object should have a property called reminder which is a string and it should have at least one character in it so it cannot be an empty string”
    • Separate Zod schemas can be defined for different operations (e.g., creating a reminder vs. updating a reminder).
    • “now we need to define different this is our main basically object schema that we have in our database for these reminders and here I said uh yeah no so for these reminders so it has an ID reminder notes all of these fields basically but now we need to define a separate schemas for when we’re trying to create and when we’re trying to update”
    • The validation middleware uses the .parse() method of a Zod schema to validate the request body.
    • “this middleware will receive uh in here the request response and next … this middleware will try to call the schema that we passed and parse it with the request body”
    • If validation fails (ZodError), the middleware extracts and formats the validation errors into a user-friendly response with a 400 status code.
    • “if the library is a zod error it means the request body did not match the schema that we were expecting so that means that we will try to build this error message in a human readable way … and then we’re returning the error with status 400 and saying that the data was invalid”
    • The validation middleware is applied to specific routes before the controller function using router.post(‘/reminders’, validateData(createReminderSchema), remindersController.create);.
    • “before calling this function we will add a validate data and we are also need to if you remember pass the schema to this validate data function”

    Part 5: Custom Error Handling

    Main Themes:

    • Consistent Error Responses: Implementing custom error handling ensures that the API returns consistent and informative error responses to the client.
    • Custom Error Class: A custom CustomError class extending the built-in Error class is created to include a statusCode property.
    • Static Error Messages: Using constants for common error messages (e.g., “Reminder not found”) promotes consistency and simplifies future changes or internationalization.
    • Error Handling Middleware: An Express middleware is created to catch errors that propagate through the route handlers. This middleware formats the error response, including the status code and message.

    Key Ideas and Facts:

    • A CustomError class allows for passing a specific HTTP status code along with the error message.
    • “what this code does is we are creating a constructor our own class which will extend the error class that we already have here … but because we this error class does not have a status code we will call this and we’ll say the status code will be the status code that we provide in when we’re calling our custom error”
    • Defining error messages as constants in a separate file (errorMessages.js) improves maintainability.
    • “what a lot of companies are doing they create these constant static error messages and they reuse them that’s a very good practice of doing that it prevents the typos it keeps the code very clean consistent and later on you can even translate everything all of these very easily”
    • The error handling middleware checks for a statusCode in the error object and uses it to set the HTTP status of the response. If no status code is found, it defaults to 500 (Internal Server Error).
    • “this error handler receives the error and it checks like okay does the error have a status code … if it has it will apply it if it doesn’t it will throw 500”
    • Route handlers use the next(error) function to pass errors to the error handling middleware.
    • “instead of calling right away this error we will say call next and we already uh saw this next and it means that call next middleware or yeah or router or whatever”
    • The error handling middleware should be the last middleware registered in the Express application to catch errors from all preceding middleware and route handlers.
    • “you need to add this middleware as the last one … because if like as I said like it’s calling the next middleware so it’s going to call this one after the routes”

    Part 6: React Native Frontend Setup with Expo Router and Tailwind CSS

    Main Themes:

    • React Native with Expo: The frontend is being built using React Native with the Expo framework, providing tools and services for development, building, and deployment.
    • Expo Router for Navigation: Expo Router is used for file-system-based routing and navigation in the React Native application.
    • Tailwind CSS for Styling: Tailwind CSS is integrated for rapid styling using utility classes.
    • Basic Project Structure: The frontend project follows a structure with source, app (for screens and routes), and components (for reusable UI elements) folders.
    • Path Aliases: Path aliases (@/) are configured in tsconfig.json to simplify import paths.
    • Layout Component: A root layout component (_layout.tsx) is used to define a consistent UI structure (e.g., headers using Stack) that wraps around different screens.

    Key Ideas and Facts:

    • A new React Native project with TypeScript and Expo is created using npx create-expo-app@latest –template tabs@50.
    • “now we are going to wait a second it created it so now we can go to our VS code on file open recent uh or no actually open and then we are going to go to uh documents projects and here we should have apple reminders clone let’s open this project”
    • The frontend application is started using npx expo start.
    • “click on terminal new terminal and in here simply write mpx expo start”
    • Expo Go app can be used to preview the application by scanning a QR code provided by expo start. Simulators can also be used for development.
    • “if you’re using Go if you’re using Expo Go simply scan this QR code and you will right away see the application on your phone just as easy as that no setup nothing for me as I mentioned I will be working with a simulator just to show it uh on the screen”
    • Expo Router is installed using npm install expo-router react-native-safe-area-context react-native-screens.
    • “we’ll be installing now the Expo router for our navigation as mentioned so to do that … we need to install all of these dependencies and actual exper itself”
    • The main entry point in package.json is changed to app to use Expo Router’s file-based routing.
    • “inside here where it says main and right now it’s index j index.ts TS which is here we need to say okay we will change it and now we will uh use the export router entry which is going to be the app folder in a way”
    • Tailwind CSS is installed and configured in the frontend project using npm install -D tailwindcss postcss autoprefixer && npx tailwindcss init -p.
    • “we will use Tailwind CSS for styling and I’m a huge fan of it and I use it in all of my projects and it really speeds up the development a lot so let’s install it by running this command uh we’ll do it with npm”
    • A tailwind.config.js file is created to customize Tailwind CSS.
    • “now that we installed it we need to initialize it and create our tailwind config file by running this command”
    • The global.css file is modified to include Tailwind directives (@tailwind base, @tailwind components, @tailwind utilities).
    • “now we need to go to our styles folder and inside global CSS we need to add these three directivs”
    • Tailwind CSS classes can be directly used in React Native components’ className prop via react-native-tailwindcss.
    • “to make it work what we need to do is we need to import tw from react native tailwindcss … and then we can use className prop in our elements”
    • The _layout.tsx file in the app directory defines the root layout for the application, often using Stack from expo-router to provide header navigation.
    • “in order to think of the um in order to showcase how it works we can create this layout file and let’s create it inside the app and let’s make it layout tsx … inside here let’s return and let’s return a slot from uh actually not a slot stack will be a better example let’s return a stack from I didn’t close sorry didn’t close the tag from react uh expert router and right away after I save you can see this header”

    Part 7: Fetching Data from the Backend in React Native

    Main Themes:

    • Fetching Data: The frontend needs to communicate with the backend API to retrieve and display data (reminders).
    • fetch API: The built-in fetch API in JavaScript is used to make HTTP requests to the backend.
    • Service Layer in Frontend: Similar to the backend, a services folder is created in the frontend to house functions that handle API calls, promoting reusability and separation of concerns.
    • Displaying Data in Components: Fetched data is displayed in React Native components (e.g., ReminderListItem).
    • Passing Props: Data (reminder items) is passed down from parent components (e.g., the screen displaying the list) to child components (e.g., ReminderListItem) using props.

    Key Ideas and Facts:

    • The fetch function is used to make GET requests to the /reminders endpoint of the backend API.
    • “now what we need to do is we need to get our URL the same way as we were doing inside insomnia so for example let’s we’re trying to get all reminders so let’s copy this go back to our code and let’s say okay let’s call uh this basically function”
    • Response from fetch needs to be parsed as JSON using .json().
    • “yeah this response should be parsed to JSON”
    • Frontend service functions encapsulate API call logic and return the fetched data.
    • “creating a services folder inside source and inside this services we will provi provide create reminders or maybe reminder service.ts and in here we can like create all of these different functions that will have all of the logic and that we’ll be able to reuse”
    • Data fetched in a screen component is passed as props to the ReminderListItem component to render individual reminders.
    • “we will have a reminder list which will map through all of the reminders that we fetched and for each reminder it will render this reminder list item component and very importantly we will pass down each reminder as a prop”
    • Props are accessed in the child component through the props object or by destructuring. Types can be defined for the props a component expects to receive using TypeScript interfaces or types.
    • “this is how we pass the data by simply adding this as an attribute but now in the child component which is reminder list item how do we receive it well we simply define here uh curly braces and we say props and now inside here I can access this data by saying props dot reminder”

    This briefing document captures the initial stages of building a React Native application with a NodeJS backend, covering the fundamental setup, API creation, database integration, data validation, error handling, and the initial structure for the frontend. The focus is on practical, hands-on learning with a structured approach and separation of concerns through established architectural patterns and best practices.

    React Native Course: Backend Setup and API Basics

    React Native Course and Resources

    1. What is this course about, and what will I learn? This course is a comprehensive guide to learning React Native. By following along and writing your own code, you will ultimately build a functional app. The course covers everything you need to know about React Native in detail, including guides and videos. It also includes educational exercises after each lesson to further enhance learning.

    2. Who is the instructor behind this course? The instructor is a software developer with several years of experience in the field. They have a background as a startup CTO and co-owner for over six years and previously served as a university instructor in software engineering. The instructor identifies as a developer first and an educator second, emphasizing learning through hands-on experience and a desire to share their knowledge.

    3. Is there any supplementary material or a step-by-step guide available for this tutorial? Yes, there is a step-by-step guide available that accompanies this tutorial. You can download it by following a link provided in the description of the live stream or potentially near the video title. After clicking the link, you will need to provide your name and email address, and the guide will be sent to you. This guide includes introductions to the topics and the tech stack used. The instructor also mentions updating the documentation based on feedback.

    4. What is the tech stack used in this initial setup? The initial setup focuses on the backend using: – Node.js: A JavaScript runtime environment used to execute JavaScript code outside of a web browser. – npm (Node Package Manager): Used for managing project dependencies, such as installing frameworks and libraries. – Express: A minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. – pg (node-postgres): A PostgreSQL client library for Node.js, used to interact with a PostgreSQL database. – dotenv: A library used to load environment variables from a .env file into process.env.

    5. How is the backend project initially set up? The initial setup involves the following steps: – Ensuring Node.js is installed on your machine. – Creating a new project directory. – Navigating into the new directory using the terminal (cd). – Initializing npm for the project (npm init). – Installing the Express framework (npm install express). – Enabling ES6 modules by adding “type”: “module” to the package.json file. – Creating a source folder and an entry file index.js within it. – Writing a basic Express application in index.js to listen on a specified port and return a “Hello World” message on the root route. – Starting the server using node source/index.js.

    6. What are environment variables and why are they used in this project? Environment variables are dynamic named values that can affect the way running processes will behave on a computer. In this project, they are used to store configuration values such as the server port and later, database connection details. The benefits of using environment variables include: – Security: Sensitive information like API keys and database passwords are not hardcoded directly in the application. – Configuration: Different environments (e.g., development, production) can have different configurations without changing the code. – Best Practices: Hardcoding configuration values is considered insecure and bad practice.

    A .env file is created to store these variables locally. The dotenv library is used to load these variables into the Node.js process. The .env file is also added to .gitignore to prevent sensitive information from being committed to version control.

    7. How is API testing introduced in this tutorial? The tutorial introduces API testing using a tool called Insomnia (though alternatives like Postman and Bruno are also mentioned). Insomnia allows you to create and send HTTP requests to your backend API endpoints and inspect the responses. The process involves: – Downloading and installing Insomnia. – Creating a new project or collection within Insomnia. – Creating new HTTP requests (e.g., GET, POST) with the appropriate URL (including the correct port). – Sending the requests and observing the responses to verify if the API endpoints are working as expected.

    8. What is the purpose of database migrations in this project? Database migrations are changes to a database schema that are version controlled. They provide a structured way to evolve the database over time, ensuring consistency across different environments. The tutorial demonstrates creating migration files (with timestamps and descriptive names) that contain SQL code to modify the database schema, such as creating tables and defining their columns. The process involves writing “up” functions to apply changes and “down” functions to revert them if necessary. While the tutorial simulates migrations with individual .js files and direct execution via Node.js, it mentions popular migration tools like Knex, Sequelize, and Prisma that automate this process in real-world applications.

    Serverless PostgreSQL with Neon for a Reminders App

    The tutorial focuses on setting up and configuring a PostgreSQL database using a serverless platform called Neon for a full-stack Apple reminders clone application.

    Database Choice and Types:

    • The application uses PostgreSQL, a popular relational database.
    • The tutorial briefly discusses three main types of databases:
    • Self-hosted databases: Require manual installation, configuration, and maintenance, offering full control but demanding significant expertise.
    • Managed databases (e.g., RDBS): Cloud providers manage backups, scaling, and maintenance, suitable for constant high traffic but can be expensive if not optimized.
    • Serverless databases (e.g., Neon): Fully cloud-managed, automatically scale based on demand, and offer a pay-as-you-go model, ideal for startups and unpredictable workloads due to ease of setup and cost-efficiency, including a free tier.
    • Neon is the chosen serverless PostgreSQL database for this project due to its ease of use, elimination of maintenance tasks, automatic scaling, and a generous free tier.

    Setting up a Neon Database:

    • The setup process involves navigating to the official Neon website, creating a new account, and then creating a new project.
    • During project creation, you need to provide a project name (e.g., reminders API), a database name (which can be left as default or specified, e.g., reminders_database), and select a region closest to the target audience.
    • After creation, the Neon dashboard provides a connection string that will be used to connect the backend application to the database.

    Database Connection Configuration:

    • The tutorial utilizes the pg (node-postgres) library, a common and performant library for executing SQL queries in Node.js, which also supports connection pooling.
    • For secure configuration, the database connection string obtained from Neon should be stored as an environment variable. This is done by creating a .env file in the root of the project and adding a variable like DATABASE_URL with the connection string as its value.
    • Hardcoding sensitive information like the database URL directly in the application code is strongly discouraged due to security risks.
    • The .env file should be added to the .gitignore file to prevent it from being committed to version control systems like Git, thus avoiding accidental exposure of sensitive credentials.
    • The database connection is established in a dedicated configuration file (e.g., db.js inside a config folder). This file imports the pg library and creates a connection pool using the DATABASE_URL fetched from the environment variables using process.env.
    • A test function can be included in the configuration file to verify the database connection by executing a simple query (e.g., SELECT version()) and logging the result.

    Database Migrations:

    • Database migrations are introduced as a crucial practice for managing changes to the database schema in a version-controlled manner. This ensures consistency across different development stages and environments.
    • While popular migration tools like Knex, Sequelize, and Prisma exist, the tutorial opts for a more manual approach to illustrate the underlying concepts.
    • A migrations folder is created in the src directory to house migration files.
    • Each migration file is typically named with a timestamp followed by a descriptive name (e.g., 1678886400000_create_user_table.js).
    • Each migration file exports two asynchronous functions:
    • up: Contains the SQL code to apply the database changes, such as creating tables and adding columns. The CREATE TABLE IF NOT EXISTS command is used to prevent errors if the table already exists.
    • down: Contains the SQL code to revert the changes made by the up function, typically by dropping tables (e.g., DROP TABLE IF EXISTS users).
    • The tutorial emphasizes the use of raw SQL queries for database interactions to foster a deeper understanding of SQL. Examples are provided for creating users and reminders tables with specified data types, constraints (like PRIMARY KEY, UNIQUE, NOT NULL, DEFAULT), and foreign key relationships (REFERENCES with ON DELETE CASCADE).
    • Migrations are executed using Node.js by running a script that loads the environment variables using dotenv/config and then executes the up (or down for rollback) function in the specified migration file.
    • The tutorial demonstrates how to run a migration to create the users table and then the reminders table. It also shows how to roll back a migration by running the down function, effectively dropping the reminders table as an example.

    In summary, the database setup and configuration in this tutorial involve choosing PostgreSQL hosted on the serverless Neon platform, securely configuring the connection using environment variables, and managing database schema changes through manually created and executed migration files using raw SQL queries.

    Neon PostgreSQL: Database Table Creation via Migrations

    The sources discuss creating database tables primarily within the context of using database migrations with PostgreSQL on the Neon serverless platform. Migrations are described as version-controlled changes to the database schema, allowing for structured management of these changes across different environments.

    Here’s a breakdown of the process based on the tutorial:

    • Migration Files: Database tables are created through migration files located in a migrations folder within the src directory of the project. Each migration file typically has a timestamp and a descriptive name, like 1678886400000_create_user_table.js.
    • up and down Functions: Each migration file exports two asynchronous functions:
    • up: This function contains the SQL code to create the database tables and add columns. The tutorial emphasizes using raw SQL queries for this purpose. The CREATE TABLE IF NOT EXISTS command is used to ensure that a table is created only if it does not already exist.
    • down: This function contains the SQL code to revert the changes made by the up function. For table creation, this usually involves dropping the table using DROP TABLE IF EXISTS.
    • Creating the users Table (Example): The tutorial provides an example of creating a users table:
    • CREATE TABLE IF NOT EXISTS users (
    • id SERIAL PRIMARY KEY,
    • name VARCHAR(100) UNIQUE NOT NULL,
    • created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    • );
    • This SQL code defines a table named users with the following columns:
    • id: An automatically incrementing integer that serves as the primary key (SERIAL PRIMARY KEY).
    • name: A string with a maximum length of 100 characters, which must be unique and cannot be NULL (VARCHAR(100) UNIQUE NOT NULL).
    • created_at: A timestamp that defaults to the current timestamp when a new record is created (TIMESTAMP DEFAULT CURRENT_TIMESTAMP).
    • Creating the reminders Table (Example): The tutorial also demonstrates creating a reminders table:
    • CREATE TABLE IF NOT EXISTS reminders (
    • id SERIAL PRIMARY KEY,
    • reminder VARCHAR(255) NOT NULL,
    • notes TEXT,
    • completed BOOLEAN DEFAULT FALSE,
    • user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
    • created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    • );
    • This SQL code defines a table named reminders with these columns:
    • id: An auto-incrementing integer serving as the primary key (SERIAL PRIMARY KEY).
    • reminder: A string with a maximum length of 255 characters that cannot be NULL (VARCHAR(255) NOT NULL).
    • notes: A text field that can be empty (TEXT).
    • completed: A boolean value that defaults to FALSE (BOOLEAN DEFAULT FALSE).
    • user_id: An integer that establishes a foreign key relationship with the id column of the users table (INTEGER REFERENCES users(id)). The ON DELETE CASCADE clause specifies that if a user is deleted, all associated reminders will also be deleted.
    • created_at: A timestamp that defaults to the current timestamp (TIMESTAMP DEFAULT CURRENT_TIMESTAMP).
    • Executing Migrations: These migration files are executed using Node.js scripts. The script typically loads environment variables (including the database connection string) and then calls the up function of the specific migration file to apply the schema changes to the database. Similarly, the down function can be called to roll back the changes.

    In summary, creating database tables in this tutorial involves defining the table schema in migration files using SQL CREATE TABLE statements within the up function. These definitions include specifying column names, data types, constraints, and relationships with other tables through foreign keys. The migration files are then executed to apply these changes to the PostgreSQL database.

    ExpressJS REST API Route Definition

    The source discusses defining API routes within the context of building a REST API using ExpressJS. Here’s a breakdown of how API routes are defined according to the tutorial:

    • Basic Route Definition: API routes are defined using the methods provided by the Express application instance (app). These methods correspond to HTTP request methods like get, post, patch, and delete. For example:
    • app.get(‘/reminders’, (req, res) => { … }); defines a route that handles GET requests to the /reminders path.
    • app.post(‘/reminders’, (req, res) => { … }); defines a route that handles POST requests to the /reminders path.
    • Similar methods exist for patch and delete requests.
    • URL Paths: Each route is associated with a specific URL path. The tutorial uses /reminders as a base path for operations related to reminders.
    • Handler Functions: Each route is also associated with a handler function that executes when a request matching the route and HTTP method is received. These functions receive request (req) and response (res) objects, allowing you to access request data and send responses back to the client. Initially, these handler functions directly sent back simple text responses.
    • Passing Parameters in URLs: To retrieve specific resources, like a reminder by its ID, the tutorial demonstrates how to pass parameters within the URL using the colon (:) syntax. For example, /reminders/:id defines a route where :id is a parameter that can be accessed within the handler function using req.params.id. The tutorial also shows how to parse this ID to an integer if needed.
    • Separating Routes with Express Router: For better organization and maintainability, the tutorial introduces the use of Express Router. This involves the following steps:
    • Importing the Router from Express: import { Router } from ‘express’;.
    • Creating a router instance: const router = Router();.
    • Defining routes on the router instance instead of the main app instance: router.get(‘/’, (req, res) => { … });.
    • Exporting the router: export default router;.
    • Importing the router in the main application file (index.js): import reminderRoutes from ‘./routes/reminderRoutes’;.
    • Mounting the router on a specific path using app.use(): app.use(‘/reminders’, reminderRoutes);. This means that all routes defined in reminderRoutes will be prefixed with /reminders.
    • Associating Routes with Controllers: To further structure the application logic, the tutorial introduces the MVC (Model-View-Controller) plus Service layer pattern. In this setup, the route handlers in the route files (reminderRoutes.js) don’t contain the main business logic. Instead, they call functions defined in controller files (reminderController.js). This keeps the route definitions clean and focused on routing requests to the appropriate controller functions. For example, a route like router.get(‘/’, reminderController.getAllReminders); associates the GET request to /reminders with the getAllReminders function in the reminderController.
    • Handling Request Data: The tutorial explains how to access data sent with the request:
    • URL Parameters: Using req.params to access parameters passed in the URL (e.g., req.params.id).
    • Request Body: For POST and PATCH requests that send data in the request body (e.g., for creating or updating reminders), the req.body object is used. However, it’s highlighted that Express.js needs middleware to parse the request body as JSON. The express.json() middleware is used for this purpose: app.use(express.json());. This allows accessing the JSON data sent in the request body.

    In summary, the tutorial advocates for a structured approach to defining API routes using Express Router to separate route definitions, associating these routes with controller functions for handling logic, and using appropriate methods to access request data. This structure promotes a more organized and maintainable codebase.

    Full-Stack Reminders Clone: Implementing CRUD Operations

    The source material discusses implementing CRUD (Create, Read, Update, Delete) operations within the context of building a full-stack Apple Reminders clone using React Native Expo, Express.js, and PostgreSQL. The tutorial emphasizes a structured approach using a REST API with ExpressJS on the back-end.

    Here’s a breakdown of how CRUD operations are implemented according to the source:

    1. Defining API Routes:

    • API routes are defined using methods of the Express application instance (app) that correspond to HTTP request methods:
    • GET for reading data (retrieving all or a specific reminder). For example, app.get(‘/reminders’, …) to get all reminders and app.get(‘/reminders/:id’, …) to get a reminder by its ID.
    • POST for creating new data. For example, app.post(‘/reminders’, …) to create a new reminder.
    • PATCH (or PUT) for updating existing data. For example, app.patch(‘/reminders/:id’, …) to update a specific reminder.
    • DELETE for removing data. For example, app.delete(‘/reminders/:id’, …) to delete a specific reminder.
    • For better organization, Express Router is used to separate route definitions into dedicated files (e.g., reminderRoutes.js). These routers are then mounted on specific paths in the main application (index.js) using app.use().

    2. Controller Layer:

    • The defined API routes are associated with functions in controller files (e.g., reminderController.js).
    • Controllers act as intermediaries, receiving requests and sending responses. They do not contain the main business logic.
    • Controller functions call corresponding functions in the service layer to handle the actual data operations.
    • Error handling is implemented within the controller using try…catch blocks to manage potential errors during service calls and send appropriate error responses to the client.

    3. Service Layer:

    • The service layer (e.g., remindersService.js) contains the core business logic for each CRUD operation.
    • Service functions receive data from the controller, perform operations (like data validation or sanitization), and interact with the model layer to access the database.
    • Services can also interact with other services or external APIs if needed.
    • The service layer can throw errors if operations fail, which are then caught by the controller.
    • For example, reminderService.getAllReminders() would fetch all reminders by calling the model, reminderService.getReminderById(id) would fetch a specific reminder, reminderService.createReminder(data) would create a new reminder, reminderService.updateReminder(id, data) would update an existing one, and reminderService.deleteReminder(id) would delete a reminder.

    4. Model Layer:

    • The model layer (e.g., reminderModel.js) is responsible for directly interacting with the PostgreSQL database.
    • It contains functions that execute raw SQL queries for each CRUD operation.
    • Each function in the model performs a specific database operation:
    • reminderModel.getall(): Executes a SELECT * FROM reminders ORDER BY created_at DESC query to retrieve all reminders.
    • reminderModel.findById(id): Executes a SELECT * FROM reminders WHERE ID = $1 query to retrieve a reminder by its ID. Placeholders ($1) are used for security against SQL injection, and the actual ID is passed as a parameter.
    • reminderModel.create(data): Executes an INSERT INTO reminders (notes, reminder, user_id) VALUES ($1, $2, $3) RETURNING * query to create a new reminder. The data (reminder, notes, user ID) is passed as parameters to the query.
    • reminderModel.delete(id): Executes a DELETE FROM reminders WHERE ID = $1 query to delete a reminder by its ID.
    • The update operation (reminderModel.update) is built dynamically in the service layer based on the fields to be updated and then executed by the model.
    • The model functions use the pg library to connect to the PostgreSQL database and execute the SQL queries.

    5. Database Migrations:

    • Database tables (like users and reminders) are created and managed using database migrations.
    • Migration files contain SQL code to define the table schema (CREATE TABLE) in the up function and to revert these changes (DROP TABLE) in the down function.
    • These migrations ensure that the database schema is consistent across different environments and versions of the application.

    6. Schema Validation:

    • Zod is used for schema validation to ensure that the data received from the client during create and update operations is valid and matches the expected format.
    • Schemas are defined for creating (createReminderSchema) and updating (updateReminderSchema) reminders, specifying data types, required fields, and constraints (e.g., string length).
    • A middleware (validateData) is created to apply these schemas to the incoming requests before they reach the controller. This middleware uses Zod to parse and validate the request body against the defined schema. If validation fails, an error response is sent back to the client; otherwise, the request proceeds to the controller.

    7. Handling Request Data:

    • Request parameters (from the URL, e.g., /reminders/:id) are accessed using req.params.
    • Data sent in the request body (for POST and PATCH requests) is accessed using req.body. The express.json() middleware is used to parse the request body as JSON.

    8. Front-end Interaction (Briefly Mentioned):

    • The front-end (React Native Expo) will make API requests to these defined routes using methods like fetch or a library like Tanstack Query.
    • Tanstack Query mutations are used on the front-end to perform create, update, and delete operations. These mutations send requests to the back-end API routes and handle the responses. On successful mutations, the front-end cache is invalidated to reflect the changes.

    In summary, the implementation of CRUD operations in this tutorial follows a well-structured, layered architecture. API routes are defined to handle client requests, controllers orchestrate the flow, services contain the business logic and interact with the data through models using raw SQL, and database migrations manage the underlying database schema. Input validation ensures data integrity, and error handling provides a robust user experience.

    Building a React Native UI with Expo Router

    The source discusses building React Native UI as part of creating a full-stack Apple Reminders clone. Here’s a breakdown of the key aspects discussed:

    • Core UI Library: The front-end is built using React Native and Expo. React Native is described as the primary tool for the front-end.
    • Fundamental React Native Concepts: The tutorial emphasizes the importance of props and state as the “bones” of React Native for managing data. React Hooks, specifically useState and useEffect, are highlighted as essential for functional components.
    • Basic UI Components: The tutorial utilizes fundamental React Native components such as:
    • View: Used as a container for other components.
    • Text: Used to display text.
    • TextInput: Allows users to input text.
    • Pressable (or TouchableOpacity): Enables components to respond to user touches.
    • ActivityIndicator: Displays a loading indicator.
    • FlatList: An optimized component for rendering dynamic lists of data.
    • SafeAreaView: Ensures content is rendered within the safe area of the device screen, avoiding notches and status bars.
    • Layout and Styling:
    • Flexbox (flexDirection, alignItems, justifyContent) is used for arranging UI elements.
    • Inline styles can be applied directly to components.
    • StyleSheet.create from React Native is introduced as a better practice for organizing and reusing styles. This allows for defining styles in a separate object and applying them to components using the style prop.
    • Properties like margin, padding, borderWidth, borderColor, fontSize, fontWeight, and color are used for styling.
    • alignSelf is used to align individual items within a flex container.
    • gap is used to create spacing between items in a flex container.
    • width and height (including percentages) are used to control component dimensions.
    • Navigation:
    • Expo Router is used for screen navigation.
    • The main entry point for routes is within the app directory.
    • Link component from Expo Router is used for declarative navigation between screens. The href prop specifies the target route.
    • Layout files (_layout.tsx) are used to create wrappers around screens, allowing for persistent UI elements like headers.
    • Stack from Expo Router provides a stack-based navigation pattern with headers and back functionality. stack.screen within the layout allows configuring options for individual screens, such as hiding the header (headerShown: false) or setting the header title (headerTitle).
    • Programmatic navigation is possible using the router object from Expo Router, specifically router.back() to navigate back.
    • Modal presentation (presentation: ‘modal’) is available for screens, providing a modal-like transition.
    • Displaying Lists of Data:
    • The FlatList component is used to efficiently render lists of data.
    • It requires a data prop, which is an array of items, and a renderItem prop, which is a function that takes an item and renders the corresponding UI.
    • The item prop within renderItem provides access to each individual data object in the list.
    • Props can be passed down to custom list item components within the renderItem function.
    • keyExtractor can be used to provide unique keys for each item in the list, improving performance [Not explicitly shown in the excerpt, but a common practice with FlatList].
    • ListHeaderComponent can be used to render a component at the top of the list.
    • showsVerticalScrollIndicator can be set to false to hide the vertical scroll bar.
    • Handling User Input:
    • The TextInput component is used to capture user input.
    • The value prop binds the input’s value to a state variable.
    • The onChangeText prop is a function that is called whenever the text in the input changes, allowing you to update the state variable.
    • The multiline prop allows for multi-line text input.
    • Reusable Components: The tutorial emphasizes creating reusable UI components (referred to as “Lego pieces”) to make the code more modular and maintainable. This involves creating separate component files (e.g., ReminderListItem.tsx) and passing data to them via props.
    • Conditional Rendering: UI elements can be rendered conditionally based on certain conditions, such as the completed state of a reminder. This is often done using ternary operators or if statements within the JSX.
    • Type Safety with TypeScript: TypeScript is used to ensure type safety in the React Native code. This helps in catching errors early during development. Types are defined for props and state.

    The source provides a practical, hands-on approach to building a React Native UI by demonstrating how to use various components, manage layout and styling, implement navigation, display dynamic data in lists, and handle user interactions within the context of a real application.

    Build Your First Full-Stack Application (beginner tutorial) 🔴

    The Original Text

    hello and welcome back everybody uh today’s going to be a fun one because we will be building a full stack Apple reminders clone with React Native Expo Express.js and PostgreSQL so if you’re a beginner looking to take your first steps into full stack development I think you’re in the right place because we’ll start from scratch break things down step by step and by the end you’ll have a working app and the confidence to build even more so grab a coffee get comfy and let’s dive in so as I mentioned we will be working on a full stack Apple reminders clone uh we’ll be working with mainly with React Native Expo PosgreSQL and Express.js and I’ll cover more technologies that we’ll touch uh a little bit later but this is going to be our basic fundamental technologies so let’s dive a bit further and check out how our application will look like so first of all uh it’s not going to be as fancy on the front end because I will try to focus a little bit uh more on the back end and um therefore it’s uh yeah I want the beginners to have their first steps and to feel comfortable to get a good grip of how to structure their back end how to structure their front end how to tie everything together basically to help them either start their career or at least have good fundamentals to find a job the things that are like very needed to know but as a junior developer so let’s continue we’ll be working also on create new reminder screen so here we’ll be able to create those reminders we’ll be able to provide a title and some notes bas basically then we’ll be working also on updating uh or deleting these reminders so yeah if you created like a wrong reminder or you uh just don’t want to have it anymore you’ll be able to delete them modify them and so on so the technologies that we will use mainly will be for the back end uh NodeJS as our JavaScript runtime environment also uh accompanying that we’ll use ExpressJS as our framework which is a very popular combination then for our database we’ll be using Posgra SQL and it’s a relational database it’s a very popular one and I think most of the corporations use that so it’s going to be very good to know how to use it how to write uh SQL queries and I’ll touch a little bit more upon it later and also we’ll use ZOD for schema validation if you use uh any other technology for this you can totally do that i just feel that this is something I’m mostly comfortable with and that’s why I will use this and it’s a very popular one as well so it’s not bad to know it then for our front end we’ll be using React Native and Expo and I think that’s not a surprise to anybody because on this channel this is mainly what we use so yeah that’s nothing new here then we will be using expert router for our screen navigation we’ll see how to use it and how to implement then we’ll be using TypeScript to ensure type safety i’ll basically cover all the basics of it uh so you could understand how to write types how to why is it good and why you would need that it’s going to be very good to know and lastly we’ll use tanstack query for data fetching and caching our data so yeah this is our tanstack so let’s quickly recap and basically understand what are you going to learn in this live stream mainly we’ll be working uh and creating a a REST API with ExpressJS u so this is a very general topic but I’ll dive a little bit deeper uh what we will learn now so yes we’ll cover database database management using Postgress SQL for the data persistence how to store it how to retrieve data and much more then we’ll be working on schema validation to know that basically the inputs that we are receiving from the user are they correct and automate this a little bit better um then we’ll be learning how to handle the errors and the best practices to handle these errors correctly uh because there’s a lot of different ways and uh you can structure it differently so this is also quite important to know uh then again we’ll cover on the project structuring and how to structure it and organize for a let’s say easily maintainable uh application so this is also going to be very good to know for beginners because a lot of big corporations uh will be using this kind of structure it’s a very popular structure and knowing this will help you let’s say understand everything a lot faster of course we need to learn how to do the main CRUD operations uh so creating new records reading them updating them and deleting them from the database and also we’ll learn database migrations so how to manage them how to create them how to run them write them and stuff like that uh so for the front end now let’s see what we will cover here as well so as always props and state that’s very important to know that’s basically bones of uh React Native and managing the data so we’ll cover that we’ll be covering the flat list and how to create dynamic lists then we’ll check how to work with navigation how to navigate between screens and um yes like that then as mentioned TypeScript uh React hooks which is very essential uh to know especially the use state and use effect and we’ll see how they work they’re let’s say one of the more popular ones then we’ll learn how to make the API request request to our back end that we will create from the front end our application and that’s it so now let’s cover a little bit why I think the project based learning is the best way to learn and uh well first of all building uh you build the realw world apps you build them you don’t uh study too much theory but you understand the theory along the way you see how everything ties together and it’s very important this is actually how I learned and how I was taking my first steps and I would recommend that to every everybody then again you are getting as mentioned hands-on experience instead of just theory so it’s very interesting to see how everything ties together and um yeah witnessing that by writing your your own code and then again at the end you will walk away with a functional app that you can uh show to whoever you want and say yeah this is what I’ve built so let me quickly also talk about myself and uh who am I so I am a software developer i have quite a few years experience in this field and I am already only like let’s say six plus years u startup CTO and co-owner um then I was also former and university instructor in software engineering and we did that together with Vadim so shout out to him as well and I believe uh I always like to say I’m a developer first and educator second because I learned everything uh by heart i tried I failed and now I think it’s time I developed a lot of things and now I think it’s time to share my knowledge and maybe sometimes you see there is issues where you forget your microphone but that’s why I’m only learning to educate and share my knowledge the best way I can so that’s a little bit about me i think we can get started and uh start getting our hands dirty as they say so let I will meet you in a second but we are still here so but before we go and do uh anything else I just really want to um tell you about this course that Vadim was working tirelessly on for a very very long time and we’re finally done with it we are editing the last few lessons and we’ll be publishing it but you can already check it out you can already enroll to it it has everything that you need to know about React Native completely everything in very very much detail with the huge guides and videos so if you are considering if you are looking for a well ststructured course in React Native I highly suggest you to check it out and uh you will definitely not regret it vadim is actually currently even working to adding uh after each lesson each workshop that you learn uh educational exercises so it’s going to have even more value so guys check that out and I’ll be using a step-by-step guide in this tutorial that you can download by going to this to this link or going to the description of this live stream and finding and clicking on a link uh very similar actually the same link it’s going to be near the title saying uh get your asset bundle and step-by-step guide and um after clicking on this link you’ll need to provide your name and an email and we’ll send this guide that I will show you in a second uh to your email address so then you can reuse it anytime you want any changes I will do in the future you can get on that guide and check it out usually after the streams I try to improve the documentation if I see that people are having issues with certain uh topics I try to add more and u yeah make it even better so check it out if you need it but if you don’t need it it’s okay not to download it but yeah so let me show you this guide that I was talking about and uh we can close this off so yeah this is the guide uh in here I have like a short introduction of what we will try to learn of the text tag that we will use and a little bit more of the information but the main meat let’s say quote unquote is in this um let me reload it is in this part here you can see basically the lessons that will be covering everything and if you click on one of these lessons you can find even more information about it And um yeah probably I will not cover in the this live stream some of the very small things that I write here as let’s say uh little uh call outs i’m not sure how to tell uh tell what they are but here also you’ll have let’s say some comparisons uh more information how to do it step-by-step guides so I’ll be using this myself along this tutorial but if you let’s say do it later on make sure to go to the description download it and you can follow it along as well together with me but our first step is going to be setting up uh well actually before getting into the meat let’s see the comment section because that can be wild yes I see a lot of different comments and um yeah that’s a lot of comments about the volume but that’s already fixed I think and let me know if it’s not too low the volume if it’s let’s say good enough uh okay mhm lucas is here amazing tutorial the walking engineer thank you thank you very much uh nice to see you here as well go Lucas Mario yeah thank you thank you catalin thank you uh can we build large scale applications using expo 150% uh I’ve done it and I’ve used it actually I am using it in my startup there’s a lot of huge applications that use uh expo and actually this is the best way to build react native applications in general and in my opinion to build applications uh uh so yeah it’s a very good um very good tool framework to use uh is 10 stack query only for front end yes now will be yes the idea of the application is so good luck Lucas uh thank you very much uh coders loi station what about style guides and test cases sir so we’ll be uh we won’t be covering test cases uh here today but again keep on suggesting uh things that you want to see in the future we can definitely expand upon this tutorial a lot more because now as I mentioned I’ll be covering like your first first first step if you want to let’s say build your own back end build your own front end so it’s going to be very low level only the most important technologies um I didn’t use over-the-top let’s say technologies so that basically I’m trying to help you uh get a job let’s say or uh build your own application and then later on we can expand on even more things with time so keep on suggesting that um can you provide the link i imagine um I’m not sure if it’s a link to the React Native Mastery or to uh I I would assume so maybe if someone is watching from the team could you uh paste a link of React Native Mastery but I believe you can also find it in the description below so yeah check it out uh can I follow this tutorial with an Android phone yes you can totally do that um it will work just the just as we will do on iOS it will look a little bit different but the the differences will be like minimal so you can definitely do that hello from Turkey hello from Lithuania hello can we get a link to this notion site okay so maybe about this notion um you can uh get a link I think I can try to copy it as well so give me a second but you can also get this this link in the description of this video um but let me actually um okay okay okay let me go here and I will try to download it i mean try to copy it and then send it to you guys okay it’s here so tell me guys how are you doing how are how is your week are you ready for the weekend or what are you going to do during the weekend do you have any plans or is it okay and of course the ads uh no um no link in the description okay that’s interesting but here it is so yeah here in this link you if you open it you will uh be redirected to our site there you need to provide your name and an email and we will send you in the email the link basically to this notion site so feel free to check it out okay think we are ready so let’s start working on it so yeah if you open this guide go to the first lesson um not coding question is the cold cucumber soup from Poland and Lithuania um I don’t know about cucumber soup we have the cold um it’s not a cucumber how is it in English like borch but uh I’m not sure how that that plant is called in English uh but it’s like a violet kind ofish but the cucumber su probably it’s from Poland i’m not sure but yeah let’s continue with that uh yes so if we go to our guide click on the first lesson set up a fresh NodeJS project and let’s see what we need to do here well first things first yes beetroot that’s our soup that leak didn’t work how is it not working it is working for me you provide the name and email and download it um yeah I’ll try to double check it with my team uh but um it should be working can okay yeah I’ll let you know in a second uh of what’s happening there oh it worked perfect then so yeah let’s now get into the meat uh so before we begin it’s very important to ensure that basically we have NodeJS installed on our machine so as I mentioned already in the presentation NodeJS is a JavaScript runtime that allows ows us to execute basically JavaScript outside of the browser so to check if you have it installed already open your ter terminal and simply write node slashv dashv probably and you should see your basically version of the node if you see some sort of an error or anything else except for this version it means you need to install it and in order to install it just go to their official uh website that I provided here and download the LTS version basically if you install it you can it’s very easy to do that and then we can continue together yeah so now because we see that we have already our node installed we can create um basically we can paste this um commands in the terminal and by by doing so we will create a new directory called Apple reminders API so first of all let me navigate to the page where I want to create it it’s going to be um yeah project documents projects and in here I will paste uh the command so first of all let’s do it one by one first of all I will create a new directory with the name of Apple reminders API so enter now if I do cd which means basically to go we can copy the name of that the directory that we just created and we will go to this directory now we are in here perfect so let’s see what we need to do next well we need to initialize our MPM to do that it’s very easy just run npm in it and that’s it so let’s copy that run it and um yeah and that’s it we are basically inside the initialization so we need to provide a few let’s say inputs here if you want you can leave them completely by default and just click enter for me this is the good name so I will click enter the version is going to be 1.0.0 so again I’m going to click enter the description it’s not it’s optional so we will not provide it enter and the entry point for us it’s going to be index.js so it’s also I’m just going to click uh enter and the test commands as I mentioned we will not be covering tests today maybe we can do it some in the other tutorials if that’s something you’re interested in but I’ll just click uh enter as well and the git repository well I highly suggest you to work with it but uh I will do it later on keywords no keywords and author well we can give author as Lucas license IC and this is basically a quick overview of what we just went through so is it okay uh yes i’m just clicking enter and that’s it we’ve initialized it so now we can go uh to our uh where is it let me maybe rearrange a little bit like this go to VS Code if uh if you don’t have VS Code it’s um very easy to install it just um yeah you can go to your browser go to VS Code download VS Code and you will install it but if you’re using any other code editor that’s completely fine and it’s going to work just the same so now that we installed it we need to uh run mpm install express well first of all we need to open the terminal so actually not the terminal but we need to open the project that we just created so let’s click open and let’s go to our uh it’s in here in project and Apple reminders API so now if you navigate here let’s click open and we are inside our project you might get this little popup so just don’t worry click yet click yes I trust authors and that’s it we can close this welcome we can open it here and we can see yes this is exactly what we’ve provided while creating uh while providing basically those inputs so now it’s time to actually open the terminal so let’s go terminal new terminal and in here we will paste this command to install the express framework so let’s copy it paste it install it and u yeah yeah yeah it will install it very quickly and you will see that it created this package uh.lo and node modules right away and you can also see that inside our dependencies basically our project dependencies we have already express with a version of 5.1.0 zero perfect that’s very good so we can continue further now we will be enabling uh the EA6 uh modules which is in my opinion very neat it’s going to make the code a bit more readable and uh let’s say more modern uh so to do that we simply need to pass the type module in our package.json actually the only thing it will change is instead of doing uh the const uh dot basically require we will do import and then we will say what we’re importing that’s a little bit of a modern more modern way of doing that so let’s go here let’s add the type of module and continue further so now we will be creating our first entry file with a very basic basically application so you can simply copy all of this code because yeah I’m for now I’m copying the code but later on I’ll be writing myself uh but yes I will copy this one just because it’s a basic template and you will have it also in express uh documentation so we copy that code but before doing anything else what I always do uh is I create one folder called source in this folder we will keep basically all of our source um code basically all of the code that we will create now and um yeah this makes it more readable and um that’s a very good practice so inside the source we need to create our um entry file which is going to be index.js so if we create that we can paste the code that we just copied in this index uh file so let’s quickly go over what this is doing well first of all we’re importing the express that we the dependency that we just installed then we are creating the express application instance and later on we will be using it here we are simply specifying on which port we want to run our server uh so yeah you don’t need to have have it in a variable you can just pass it as a yeah like as 3000 but later on I’ll show you even a better way of having it and then we have one request already created basically to the um URL slash and this URL will basically that’s kind of a route that we’re defining and inside here we are saying okay what this route will do so when the user goes to this uh URL what’s going to happen well for now we are simply going to return hello world later on we’ll expand it and lastly we are saying here listen to the port that we define here so this in this case it’s 3000 or you can have like 3001 or yeah any other port uh that you feel is better and then um we are console logging that okay example app is listening on this port so once you have this all of this code click command S or control S if you’re on Windows to save this and now we need to run our server so if you go here uh what we will need to do is once again open the terminal you can either open it like this or with the if you didn’t close it you can run it right away here so what we will say is that we want to run our server and it from the entry point of source so going in here and index okay let’s click enter and right away we see that example app is listening on port 3000 that’s amazing so if you’re following the um if you’re following my guide that I created you can open just click on this uh link and you it will open you basically a localhost uh website or you can simply write yourself here localhost 3000 click enter and you will see hello world response so now if we go here and change hello uh not just developers if we save it then we need to restart actually we need to uh yeah restart it uh yes let’s go here loc local localhost 3000 and it changed to local hello not just developers so yeah like this is specifying the route the link that we’re going but if we would say here uh slash and not just let’s say if we go back here if we try to reload this actually yes let me for now I will show you later how to solve this and we will not need to restart it manually every time but so bear with me this would be insane but for now we do need to do that so if we go here if I’m going just to slash it says I cannot get because we don’t have any route that’s only like slash slash we have a route however with slashnotest so let’s try if it actually works like that if we say slash not justest and click enter we’re seeing that okay it works but we can specify many routes we can say uh okay so then let’s have also a route that’s only going to be slash and if we again we need to reload our server and go back here so now if we go only to slash it’s going to work to and redirect us return us a response of hello world the same is for the not just it’s still working so basically both of these routes are working well perfect let’s see what we can do to further to make it even better make the initial setup even cleaner well I will introduce you to the environment variables this is a very important file in your application your server back end because hard-coding configuration values like port numbers is quite bad and especially uh hard coding and inside not in the environment file but uh adding let’s say somewhere here inside the application your API keys is horribly bad because it’s very insecure are instead we use environment variables for that basically uh env file so you will have um you will have this file only for yourself you will not if you even if you’re using git you will not push it to let’s say um to your git uh github gitlab whatever you use even if you have this file here uh you will need to create let’s say once you like um host everything to the cloud you will need to upload it there as well separately so yes because it’s very insecure to share these or paste hardcode these uh API keys these values inside your application anywhere so let’s just do that first of all let’s create a new environment file so to do that just in the root root uh directory click anywhere and say new file now in inside here we will say okay we’re creating dot environment file and for now we will have only the port as u as our one environment later on we will add also our de database key which is a very sensitive information and that’s why we will have mainly this environment file 4 okay but now that we added this port how can we use it somewhere in our application well to do that it’s actually pretty simple you do it and here I have an example um but yeah I will guide you through here but we are simply saying that we are taking it from proc process we’re taking it from environment and we need to then specify the environment variable name so in this case we provided the name of port so let’s copy this name and say port okay now we can save it and now this port will be taken from this environment variable which is basically what we provide after equals but let’s give it in in in case there is some kind of misunderstanding and this port is not available let’s do it and I say it here as well let’s have it uh an or statement and basically fall back to a port number 3000 so basically now we’re saying take this port value from the environment variable but if it doesn’t exist simply use 3000 okay so now you might be thinking that it should work but if I try to reload it’s still saying that we are starting on port 3000 even though we provided it well yes because our uh server doesn’t know that we already created and what kind where is this environment file uh how is it called so in order to use that we will need to uh specify in the command that we are using the environment file environment file and we called it uh env so basically we’re giving this this exact name and we’re saying that okay so this file is going to be our environment file so use that where whenever wherever we use process environment okay so now you remember I said about like always needing to stop and restart stop and restart our application well it would be insane if we had to do that after every little change so we can pass another flag called watch and what this does it basically says to the server watch for every change and whenever you I make a change here and save it reload the server automatically so that I don’t need to do it myself okay and lastly we need to say okay so now our path is in um basically entry point is in source.index so now that we have this whole command if we run it we can see that the port the app is listening on port 3001 that means our environment variables are active the uh the server is able to read them and now if I say let’s say I remove this and save it you can see that it’s restarting also automatically our server so we no longer need to do that manually anymore well that’s amazing but remembering this long name every time to write would be also a little bit annoying so we can create a short script and it’s a very common u way of doing it if we go to basically copy this one uh yes copy this one and if I go uh to let’s say package uh JSON under scripts we can create our own scripts so basically we will say okay well the script name will be dev and I will show you what the this name is and once I call this we need to call this whole long function so let’s save it and now if I in the terminal if I run to run our server the only thing I need to do is say npm run and then specify the name of this script so you will have quite a few scripts here like for testing and you can even have for various different things but for us the most important one is right now dev so if I say npm rundev and click enter we see that it’s running this long command and we’re listening on the port 301 amazing now the last thing that is quite important to know is also that um as I mentioned committing uh to the version control to the git the environment file would basically make this environment file useless in a way because it’s very insecure to commit such a um valuable let’s say or crucial information later that we add like our database password because is if someone gets that database password they can connect and basically remove all of our information and that’s quite bad if you probably you understand that so let’s create another file called git ignore and most likely once like when when you are working in a corporation or you have a job you will be using some sort of versioning control like either github or gitlab and they will have this git file so what in this file we specify which uh files or folders from our um from our application we do not want to push to versioning control and usually these are the files that we can configure easily ourselves or very let’s say uh private files like environment so one example would be node modules uh node modules this uh increase the font size okay I’ll try doing this way and I I’m seeing some of the comments guys i will check it out very soon after like every lesson i will try to get to your comments check it out and then we can continue right now I want to like keep it a little bit uh yeah of a flow so now yeah we specify that node modules we do not want to uh commit that because it contains well uh all of our dependencies installed it’s a very huge folder and also I can configure this folder very easily by running npm install and that’s it basically it will look inside our package uh JSON and based on the package.json it will regenerate the node modules so if I can regenerate them that easily I don’t really want them to commit them and also a very important one is the environment file and it’s because we don’t want to commit that because of what I just um talked about basically it prevents us from accidentally exposing very sensitive information so we are almost done at this like first configuration lesson it’s probably the most boring part but it’s very important to know how to configure it properly so that we could get uh get to working so now let’s close all of those uh files and I will um introduce you basically to a tool to test our API calls so of course we know that before deploying our API we want to verify that every route that we define here works perfectly like they they do what they need to do they return what we need to return and yes like that so there’s many different API to testing tools like one of the most important ones is probably a postman uh now in the recent times it’s getting like they have a lot of functionalities it’s kind of over complicated ated at this point uh to start with but you might see it quite often also insomnia is very popular one but it has a little bit in my opinion a better feel for me at least so I will be using Insomnia but feel free to use any other tool it they all work mostly the same they all do the same thing there’s one called Bruno which is also very popular now like more of a let’s say um I’m not sure like indie kind of for indie developers in a way like hipster that’s what that’s the the word I was looking for uh but it’s also very cool so Bruno is amazing okay so let’s download and install Insomnia from their official website which is insomnia rest so once you install that um I have well I already have my account but uh you will see in the main dashboard uh something like this saying that here’s are here are the organizations you own and uh you simply of course first of all install it in your computer you simply need to press open and what this will do it will open insomnia for you and you will see actually exactly the like what you see now here so what we need to do now well first of all I I want to create a new project uh because I want to create it locally and I don’t want to always sync it with my cloud if you’re working with a team you will most likely always choose like the cloud sync and for that you already have one project created but I only want I want to store everything locally for for this project um yeah so it doesn’t really matter too much for you um if you’re working in a company uh they will say which one to use if they are using their own they will probably import in your computer so yeah let’s call it something like personal uh local project and click create or continue then the name now in here let’s click on new collection and let’s call our collection so we will call it reminders API and let’s click create now you will see something like this basically a blank space with u not much so yeah here I have all of the things you need to know and now we’re here uh the creating your first API request it’s actually kind of easy to do you simply click here on a little plus sign you say let’s create a new HTTP request uh you can even like give it a name if you want so we can rename it and say uh get hello world something like this and um now what we need to do is you need this localhost URL here so let’s remove this and copy this local host URL actually now if you run this it’s not going to work because we are running no longer on 3000 port but it’s 3001 and I think I didn’t yes I did not run my application so let’s do mpm rundev so if we go here maybe I should increase size here as well so now if I go um if I go to this local host and on port 3001 we’ll see our old um project so now let’s copy this URL from here and go to back to insomnia in here at the top let’s paste this URL and you don’t need to add this slash because by default it is added if there’s nothing after it but I will add it just for demonstration purposes so now that we have this we see that the request is get and we know what request to use because here we say it’s get so if we go here and send this request we will get exactly the same response and let me maybe also increase it hello world but if we say here not just get we are getting hello not just developers response so it’s um yeah it is how it’s uh what we wanted to achieve in our first let’s say uh first lesson so now let’s go to the taskboard we will take a short break and let’s go to the database uh lesson now I think we can uh check out some of the comments and um yeah there’s a lot of them so probably I’m not going to be able to respond to all of them but yeah um um uh hi will you implement authentication and CSRF token handling no and in this tutorial we will not do that however I’m thinking to do like a separate tutorial for authentication only because that’s kind of like a a broad topic so I didn’t wanted to cramp everything in one uh project one tutorial because you see how deep am I going in some of the things here and I’m even explaining like the very very big like let’s say simp the simplest things quite um detail so having authentication would have been quite an overkill um okay um this is amazing regelio thank you thank you very much uh nice to see you as always in the streams that’s amazing yeah we’ll use Lucia no as I said yeah no authentication um um why not use nodebond package to run the ser uh to run the server automatically i feel this is uh like a lot easier way of doing it it’s uh everything built in you don’t need anything extra it’s very simple and very effective at this point uh do you implement MVC or just simply yes we will work on the full MVC model and that’s one of the um lessons in here we will use MVC plus service layer so basically the way how probably the biggest corporations are handling uh the ones that are using like uh let’s say express framework or even more like uh structure so we’ll cover all of that uh soon soon so yeah I think um more or less uh answered a few we’ll have a short like again burst of implementations and then we’ll come back to to to to some of the comments okay so now database um well probably kind of you know if you don’t why we need a database is basically to store and manage our data we need to somehow persist that data and uh when the user let’s say creates a new reminder we need to store it so that later when he opens his application we can actually retrieve that data and show it to him so there is a lot of different types of databases and uh for this project right away I’m saying like we will use a serverless database uh posgrade SQL as well and we’re using posgrade SQL because it’s probably the most popular I would say and it’s very good so yeah that’s that but let’s really uh quickly cover all of the t like not all but main types that you might encounter of databases so first one is self-hosted database either on your virtual machine or even on your own servers that you own this is basically where you install configure and maintain the database on your own um you have a full control yes it can be optimized like for very specific use cases but it requires insane amount of database management expertise and knowledge usually you would have your own database management team only for that so it wouldn’t it’s kind of complicated because you need to handle the backups the scaling uh everything everything yourself you need to set up and u it’s very complex so it’s not going to we are not going to be using that and if you’re working on creating your own application you’re also definitely not going to use that bigger corporations with the huge teams huge let’s say budgets may be using this uh so you might encounter this but for you nothing will change from what I will show in this tutorial then there are managed databases something like RDDS uh Google also has one um and uh basically it’s a cloud provider that manages your databases it manages the backups the scaling and all the maintenance so you kind of don’t need the full team to ma maintain it it has like automated backups and um this is probably the best suited I would say uh if you can’t really afford this for constant high traffic applications but it can be very expensive if you do not optimize it properly so basically if you leave default options this can get crazy expensive and if you don’t really know what you’re doing so you are required to fine-tune uh for the cost and performance quite well so you still need to know what you’re doing and there are uh serverless databases uh like the one that we will use today Neon there’s a lot of them there so use whichever you want i just felt this is the easiest one to use so that’s why I chose for the tutorial and it’s a good one actually also not that because it’s only easy but yeah it’s like fully cloud managed it al auto automatically scales based on the demand and we pay only for what we use so we don’t need to manage any servers it’s kind of costefficient because um for unpredictable workloads because you kind of don’t know maybe sometimes the traffic is low sometimes it’s very high so it balances out in a way it’s very easy to deploy and we’ll see how to do that and start using it however it also has some cons like uh you have less control over tuning and optimizing it potentially there might be it might be more expensive if your application is consistently having like a very high traffic but um it’s still it still can be good so it’s very difficult to say which one will be the cheapest it depends a lot on your um on your uh like use case but uh serverless if you’re working like on a startup is more more times than not will be the way to go so again why serverless well for us it’s the best choice because it’s easy to set up start using it eliminates any maintenance task it scales automatically and it has an amazing free tier so basically you can use it for free even after even uh publishing your app to production it’s still good for free for quite a bit of uh data and time only when you reach a certain threshold uh threshold you will need to go into the paid tiers again however if you’re using consist consistently high traffic applications you kind of can think about as RDS so now let’s see how to set up our database well first of all let’s just go to Neon’s official website which is um neon.te in there create a new account and after creating this new account you will see a this screen like exactly this screen maybe you will need to click click new project as well but I think it automatically opens this screen and here we need to provide the project name for our database uh so let’s say it will be reminders API uh I think I have the same so maybe Apple reminders API um database name you can provide it or you can just leave uh Neon DB we can say reminders uh database um and then you can select a region so in in theory you would select a region closest to your main target audience the people that will use your application for me I will use the one that’s closest to me uh so yeah it’s either central or west let’s say Frankfurt and then we click create now that we are in this uh okay I see there’s some a lot of questions um uh um uh hello Lucas could you please show us how to install a React Native Expo application on iPhone without going through App Store for example if you have an app you want to install among friends you mean basically not to publish your uh application to the app store so that only you and your friends could test it out and use it let me know if that’s uh that’s that real developers use Microsoft Access for database concern dodge okay uh where do you get your app designs do you do it uh or do you outsource it so it really depends uh so if you’re a small team usually you can do it yourself um for for a developer it’s good to know the basic styling but if you are let’s say in a big team big corporation more times than not they will have their own like UI UX team that will handle these things so you will only need to know how to apply these tiles but uh yeah like in a startup you would need to do it more times than not yourself unless you have a lot of investments okay let’s continue uh so now that we logged in we provided everything selected the region we will need to connect our database but before that I really quickly want to talk also about using raw SQL or OM and what is it a difference between them so um uh at a very high level an OM is a tool that uh allows us to interact with a database using object-oriented code instead of writing like raw SQL queries queries um this which makes the database operations easier to read and write so here you can see an quick example so here is how it would look in a raw SQL so you need to remember like the structure and everything it might be for some people very unintuitive and for example a drizzle or has something like this which makes it for maybe even easier to read and well again RMS have additional benefits on top of that but we are focusing on a key difference between these two and uh yeah it’s again also worth noting that many ORMs allow developers to write SQL queries when needed and it’s very it’s kind of common for well it’s not uncommon maybe that would be the better way of putting it for companies to use a mix of both like OMS for simple operations and raw SQL for performance ments but today we will be using raw SQLs because well this is a learning project and I believe and I I would argue like very harshly that it is a lot better to understand SQL and it’s a lot more valuable to learn that uh than simply relying on an RM so by working with directly with these SQL raw queries you’ll gain a very good foundation uh of database interactions and you will definitely I’ve never heard of someone trying to apply to the job and uh the uh job is saying no sorry we cannot take you in because you don’t know the ORM that we are using but not knowing an SQL queries might be a reason you are not accepted so it’s kind of important to know it it depends on your position but it is important and here you can see also like a quick uh comparison between using like uh an RM and Ross SQL why is better so main probably difference between is the performance one and the Rossql often is faster because there’s no overhead or no like abstraction I meant and um yeah but here you can read a little bit more about it and let’s I see music forever is asking why we not use superbass and you could definitely use superbass here I just thought like uh neon fits better In our case it’s only like a posgress database it’s a simple thing it’s very simple to deploy it and use it if you want you can use superbase um it’s just as good uh but here yeah I chose neon so connecting to our database yes let’s continue so in order to uh like write these uh SQL queries we need a library for that and we will use um install pg uh I mean pg which basically stands for posgress and this is the most commonly library it’s called node posgress which allows us to execute these queries and it also allow like supports uh connection pooling which is very good for performance and you can easily adapt it to any other services it’s yeah very very popular one so to install that just let’s copy this command and go back to our code let’s stop this server with Ctrl C and let’s paste this command install pg after installing it you can see that it appeared here so perfect now we need to connect to our database finally so if you go to your database uh dashboard and click here on connect you will get this uh connection string copy it in here by clicking copy snippet and go to your project for me I will um it’s not a problem to share this password because I will remove this database uh right away and I don’t I have like limits set but for you I would um be very careful by sharing this password so once we’re here let’s create some more folders to keep the structure very good let’s say in the our application so let’s click on the source and click create new folder and here we’ll create config this is where we will keep all of our configurations in this case we will have only one basically configuring our database but you might uh encounter more things in let’s say very big projects uh but what you will see definitely there is going to be db.js so in here what we need to do is um create this connection between our server and our database to do that let’s go to the environment file that I uh introduced earlier to you today and we will need to add this connection like this so we will say uh we are creating a new uh environment variable called database URL I think yes and then I will use this URL pasteed basically this connection string from here so now that we have this URL we can go uh and create this connection between um our server and the database this is the code for that uh I will copy it because there’s nothing crazy here and I will go over of what we’re doing so go to this DB and paste this code if you do not if you did not download the notion guide just pause the video and um you can write everything out but basically what we’re doing is we’re importing the pg the library that we just installed we are creating this connection pool that I talked about by simply passing the connection string from the database URL that we defined in here then in we will remove this uh function very soon but we have this function just to test if our connection is working properly so basically what are we doing here we’re connecting to this pool basically and we’re trying to query the version of our database right now and simply console log the version if it does this if it connects and uh returns me uh basically successful query that means everything is working and we can finally uh release the client otherwise uh something is not correct if it won’t return us the version so let’s see what it will return and here we’re just simply saying at the end of this file just call this function so the run this function call this function so let’s open uh our of course let’s save it and then let’s open this um terminal once again you can do terminal and new terminal or create or use a shortcut in here we will say run the script uh run the node is going to be in source uh in config and in db once we click enter uh we can oh yes it’s not going to work because we’re trying to access here the environment variables but we’re not providing okay so which where are those environments stored so we need to provide environment file env yeah here I’m talking a bit more what we’re doing here but what we can see is we have the correct response which means everything is working perfectly so now we are done with yet another lesson and we are kind of uh already 1 hour in but it’s okay I want to make it detailed so let’s go to migrations as our next lesson uh let’s open it up and we can now once again take a short break see what’s happening take a sip of water because I didn’t do that for a very long time already okay no new comments um it’s good it’s good so I think we can continue u if you have questions just let me know if you have any feedback always uh let me know as well and let’s yeah let’s do some more coding so now that we are here I hope I’m showing yes we will learn a little bit more about database migrations and here I have a huge block of text uh telling you what are they but in a way migrations are changes to a database schema that are version controlled this is very important and um we create them in order to apply these migrations and the I mean these changes in a very structured way this allows us to have basically maintain a very consistent u database schemas across different let’s say environments and typically companies will use different tools for this so there is a very popular one connects SQLize uh this is already like or even Prisma i saw someone is uh asked why I’m not using uh Prisma and um yes it’s because I really wanted to keep this whole thing very very low level and cover in much detail the things because not every company that you will apply to uh for a job will use Prisma there’s a lot of different tools that you can use instead of it and uh I just wanted to give you like a low-level knowledge of how to like create everything and work with everything and do not attach you to any of the tools that uh the company that you’re applying to is working like with different tools or with the same so yeah Drizzle is also uh a very popular one it um it also like an as an OM i gave an example with it previously so yeah but I just wanted to keep it very very low level as mentioned but so yeah these tools um help you a lot uh but we will simulate how it’s going to look like uh very very similarly so let’s first of all uh you will always have this migrations folder so let’s go to our project let’s close the config of the folder and let’s create another one inside the source called migrations inside this migrations folder you would usually use a tool to create this migration so yeah like there is it would be something to like migrate or whatever and um uh and then you would say like the the migration name that you want to apply and it will create a file similar to this first of all it will have a timestamp so let’s create today’s time stamp and it has um and then it will have a name of the basically migration that you are creating so for us it would be let’s say something I actually have some names here so yeah create user table so let’s rename it let’s create this migration called create user table and it’s more times than not uh will use this syntax also so yeah you’ll feel right at home when you see it it’s just you’re not going to create them manually so now that you created these let’s say migrations files um yeah like I’m telling here a little bit more about the naming pattern and it always will include the time stamp so how to write these migrations well here we have a little bit of an example once again um should I write it or just copy this is like a very yeah there’s a lot of setup let me copy and just go over but maybe I will like start writing them uh now let me know like should I do this setup uh setup code like in a writing everything step by step or just for now copy paste and then later on just get into the meat so for now I will paste it but yeah let me know okay so what are we doing here well first of all we’re importing the database um from this config file which is config db so in here we can see that we’re going to two like we’re going one folder back then we’re going inside config and we are uh going inside the DB um okay people are saying step by step so let me create this one like explained like this and then the reminders one we will write step by step then and from now on everything will be written step by step so here we are creating two different functions one is going to be down called down and the other one is going to be called up and this usually means we are migrating up and or we are migrating down so migrating up is usually you create some something new but if something didn’t work you create the migration down to revert the those changes back so what it means so in the up we are what we’re trying to do is creating a new table in our database so what we’re doing here we’re saying okay create table basically create a new table if it doesn’t exist yet because if it will exist it will not create and the name of the table the is called users okay now we need to specify what this table will have well first of all and almost all of the tables will have the ID which is going to be a serial uh primary key what what means it’s going to be like a primary key And uh it’s going to be auto incremented with every new record that you add so basically none of them will have the same ID all of the records different ID then it will have a name uh for the user this name can have like up to 100 characters uh and it should be unique and it can never be null so it’s a required field we need to have the user name and lastly we will have a created out uh which is going to be a timestamp and if it’s not provided once you create an every like new record new user we will default this timestamp to the current time stamp basically it will take the current time and add it as a created at and that’s it like we are running this query and if it doesn’t work we will catch it and throw an error now like how to revert this migration so if we saw that okay we migrated up but it’s something that we shouldn’t have done how to revert it back well we have for this this down function and what it does it’s simply dropping the table if it exists and the table name is users so the same as we created so yeah if we created it if we don’t need it anymore we call it down and then at the end here we will call a function so it’s either down or it’s either up usually again if you use a tool it might be something that you would simply call uh migrate up uh or migrate down or something like this it depends on the tool you’re using but for us we are going to specify it like this but like this part will look the same and you you will feel at home you will know what it’s doing so now in order to run this migration what we need to do is we need to say uh go like once again node we need to specify the environment file and it’s going to be so you could actually even create scripts for all of these if you wanted to so we are saying use environment file uh env source then we’ll go to migrations and then we will call create users table migration so now if we click enter uh we yes we are still calling this but we can go back to our it created it but we can go to our config db and remove or comment out this part because we will no longer need it we test it it works it’s good so I will remove it you can console it i mean comment it out and later uh we will you you can reuse it if you wanted to so now if we go to our neon console if I reload it um and go to tables under tables we can see a new table called users perfect with an ID as a serial with a name as we uh maybe I can make it bigger here yes with an ID as a serial uh with a name as a basically varch of up to 100 characters and created at time stamp so for example we can even create a record just in here right away and we can see that these two values have a default value but this one we do need to provide it so let’s say I will say simply Lucas and save it and it created a new record with a created at time step of actually right now but in in a different um time zone and with an ID of one well perfect so now we need to do the same for reminders and now we can try to write this uh reminders code or like migration ourselves so first of all what are we doing we’re importing the database from and we will say okay so let’s import it from config and database and adds very important unless it’s got otherwise it’s going to throw an error for you okay now that we imported we have two functions well one of them is called uh up so we will say export a synchronous it’s very important function and the name of the function is going to be up parameters it will not have any and Now we can inside it define the try catch uh so select this one the try catch right away try catch um I forgot the the word but basically yeah try catch in order to try to execute some code and if anything inside this block fails you will uh execute this so here we are again uh defining the query so we are saying await db and we’re saying query so from this DB we’re’ll execute the query and the query will be as follows so let’s adjust a little bit like this and let’s try start defining well first of all if you remember we will create uh table if it’s also very important to say if it doesn’t exist yet if not exists and now we give the name of the table which is going to be in our case reminders now we can start specifying okay what what fields will it have well first of first of all it will have ID which is once again going to be the same serial and also it needs to be a primary key i hope I’m not going to make mistakes in writing uh typos but we’ll see it because it will catch the error and console log it for us then we will add another um field uh called like reminder so we need to actually uh the actual reminder that user will save so it’s going to be again varchar and we will give it let’s say 255 characters then it also cannot be null that’s the only um like basically the most important part of our this reminders records like it’s the reminder itself that the users will save then we will have another one called notes and this can be uh empty it’s very like optional so simply a text will suffice then we will need to know if the user actually completed completed the reminder or not yet so it’s going to be a boolean basically either a true or false and if it’s not provided when we are creating we will default to false so basically because we kind of know that if the user creates a new reminder by default he’s not going to be done with it it’s a new one that means it’s still not finished then we will also need to know to which user this reminder belongs so the user will be an integer and we will reference so we say references and we need to now say the table name so if we remember here we created users table so we say it references user and it references the ID field of the user so basically this we are creating like a relationship between this user uh between this reminder and the user and also we need to say like if this user decides to remove his account so with it we need to remove all of his reminders as well because we no longer need them so we will say on user delete we will cascade and cascade means basically remove uh all of his reminders and lastly we also need created at time stamp and it’s going to be exactly the same as for the users table it’s going to be a timestamp which will default to current uh timestamp i hope I didn’t make any mistakes but if I did we’ll see as as I told already and then we will if there’s an error we will console log the error itself perfect let’s maybe add this as well here so now we need to create again another function to migrate down so let’s say uh not expo export a sync function and we will call it down and it’s not going to have any parameters it’s also going to be in a try catch block and in here we will simply say await we’ll call the DB we will also say we are running a query and the query is going to be very simple simple drop the table if exists and the table name is going to be reminders so now we will simply if it throws an error console log and console log error okay let’s save everything and now we can try to run this one as well so it’s going to be the same we were running environment file uh with and we’re running the source migrations and this migration let’s click enter now if we get go back and reload our database we are seeing that something did not work so I think I’ve made a mistake oh yes of course I made a mistake because I forgot to call the one of these functions so either because I only defined them here but I did not call anything so I’m calling now up so now if I run it again and um hopefully it’s going to work well I’m pretty sure it’s going to work okay it’s still creating it so yeah it’s done we can go try to reload it and we see the reminders table amazing now we will no longer create um records of our manually because that’s why we are here we need to know how to create them programmatically right so let’s get into our um um guide and see what’s next yeah here I explain in maybe even too much details of what are we doing here so if you have the guide you can always come back and read it again this guide is going to be always up for you if you download it like yeah and I will keep on improving it so yeah here’s some explanations and here I’m explaining of how to run it the migration and even how to roll back so yeah so for example rolling back I can show you very easily for the create uh for the create reminders we say that oh I made some sort of mistake and I forgot to add one of the fields well you could in theory create a new migration just for that but for me I am lazy so I will call for now I’m uh calling again down so basically migrate down i’m calling this same um migration and then uh we’re waiting a second while we’re waiting uh whatever I pulled that from clients how can we pull the API what do you mean exactly with that brian Harris Prasad thanks for the story bro thank you very much for watching i really really appreciate you guys staying with me on a late Friday or for some early Friday or Saturday uh yeah I really really appreciate you being here guys or any other time maybe you’re watching it after the live stream also so yeah now if we go to our console and if we reload we can see that we no longer have a reminders table because uh we rolled back we dropped this table because it existed so um but yeah but we need it so now let’s say if I made a mistake as I had an example previously I would add a new field here let’s say um not sure what you can add maybe due date something like that due date and then I would define here what it should be but we’re not going to complicate that much so we will leave this and let’s run the migration once again to uh with up to create this table I’m wondering if this is full stack yes we will cover later on um how to create the front end of this application basically your mobile app with all the reminders displayed how to interact between you the back end that we are creating right now and your front-end application uh for each load this migration check if it’s created or not i’m not sure if I understand exactly uh but yes like you would probably check if it exists or not uh always just to be safe um okay so now we can continue with our guide and go into routes this is where the things are starting to get uh more interesting maybe we’re kind of leaving the setup uh ground and um continuing kelber hello hello nice to see you here nice to see you hopefully you’re having guys a great uh evening so in this lesson as I’m stating here we’ll dive into creating uh the CRUD operations and organizing them properly so what are the CRUD operations it’s basically how we will create new data and store it in our database how we will fetch that data and retrieve it how we will update that and delete that so let’s start with a very simple and I will no longer copy my code uh although here it’s a lot of code but uh I want to show you how we do that uh step by step so now we can clo uh actually run our server and if you remember we can run it with mpm rundev click enter and now it’s watching it’s going to be reloading so we can close it we can close these migrations we will no longer need them and we can even close these folders let’s go to the index and let’s try to create different um routes so for example there might be a route uh to post so but because right now I can only get these like I can I’m only calling get routes so to get all reminders get a single reminder but what if I want to create a new reminder well in that case it’s we need to call post or to update you would either patch it or call.put uh then to delete all of them have different um different um basically requests even though for example let’s check at delete and rem and patch they have and even get they have exactly the same URLs all of them so yeah that’s that’s going to be a topic we we are dis basically discovering now a bit more so yes we will need one route which is going to get us all of these reminders and to do that well first of all we are going to call here uh slash reminders and for now let’s just return let’s say get all reminders and maybe I can even remove these comments uh too much i no longer need them okay so we have to get all reminders but I maybe want to get one reminder so in order to get only one reminder we need a way uh to pass the ID inside the URL and if you worked with web apps it’s it will be very familiar and to pass that ID we simply say like this and specify the name of the variable uh the parameter that we’re passing it could be even like name or yeah whatever for us it’s going to be we will be passing the ID because that’s how you will usually be retrieving one items items one item so get reminder by id then we also need uh one more request to create new reminder so we will say call app dot post and we will create uh new post request and a post request uh when are creating we can simply call slash reminders the same as this one then we are getting the request and response and we are say opening an arrow function inside here we are specifying okay what are we returning so we will send back to the requester to the user saying yeah you called create new uh reminder okay now I will like a little bit copy paste because here not much changes for example Here I only need to change the patch and have reminder and actually here I already made a small mistake because here I also need to say we’re calling reminders ID because that’s the best naming structure because for example if you had only like uh this and it’s a good that it’s good thing that I made this mistake it what uh what are we trying to get here are we because let’s say we have also users table so are you trying to get a user are you trying to get a reminder so to be very clear um in your back end to make the life easier for yourself and for your teammates you would usually want to be very clear uh with your naming so here we’re getting the reminder of ID even though in theory we could leave it simply like that um okay so we have a patch that we call to reminders and we also need to say okay so which uh reminder do you want to update so update old reminder and lastly we want to add exactly the same with dotdee and saying delete old reminder so now we have all of the uh most important basically routes and in a way almost all the only one that we’re not uh having is put and put and patch is basically updating both of them but patch is updating certain fields and put is updating the full uh record so now that um that we have these routes defined let’s go in our insomnia that we created a little bit earlier and say see how can we call all of these different routes because we only saw how to call the get ones so if we yeah we saved it we can see let’s go to our insomnia and or whatever if you’re using something different it’s totally fine you you might be using Postman or Bruno it will work exactly the same so now if we call our lo our URL which is going to be local host and we can see that URL uh in here basically on which port is running right now it’s local host but if you had this uh back end let’s say hosted somewhere it would be a different URL so but the everything that’s after it would be let’s say the same um so now what if we simply call slash reminders let’s See and okay it’s calling get all reminders ju just as we are what are we returning basically uh you can add here remember a lot of different codes so for example I could even say okay so before that let’s console log something hello or hello it should be hello so if we go back and now we also want to pass the ID so because if we simply call this with a get it’s gonna um it’s going to call the get all reminders and it’s a very good practice and that’s how you would do all the time create different requests in here for different requests well right so let’s say here we will have get all reminders and it’s going to get us all reminders but now we can create a new HTTP request and let’s rename it and let’s say get reminder by ID So now we need to specify a different URL so but you can kind of copy from here and paste here and just change the last part there is an even easier way in order not to like um remove the need of always defining this here so maybe I’m not going to show it because it’s only on like like that on Insomnia and it might confuse for others that are using let’s say Bruno or Postman but you can add let’s say um environment variables as well and I could use here instead of having always this local host I could have like this base URL and it will encode behind it the local host but just for not to confuse too many people let’s leave it like this so I would say reminders and then pass the ID of the reminder that I want to get so maybe let’s leave it one if I send it I can see that okay the return is get reminder by ID so exactly as we define here and we can also see that it console logged hello as we asked him to perfect let’s create all of the rest uh functions so now that we created both of the get ones we need to create uh a create request and in order to do that let’s first of all copy this URL as always but now this get here change it to post because and you can know to what it to change based on this little hint here so here we are calling post whoopsie patch delete and yeah and get so now we’re going to be calling post and even though the URL is I can simply let’s say go here copy it paste it not change anything and call it we are getting create new reminder and it’s because we are specifying which request are we doing and here we’re doing a post request and it’s also important to rename it so let’s say create new uh new reminder perfect so now we need to also be able to update these reminders if we are able to create them so let’s do go here let’s create a patch as I told there is a put one but we’ll use patch today then we’ll have um the same URL but we need to pass the ID of the reminder and I’ll show you a bit later how to get this ID from the URL that we want to update and it says update all reminder and lastly we want to be able to delete these reminders so we we can simply paste the same URL leave it as delete and call it delete all reminder perfect just rename it real quick delete delete oh my misclicks reminder then here as well update reminder perfect we have all of the requests that we will need for the reminder now we can check what’s next in our guide so now you can kind of already feel that this is crazy uh unmaintainable imagine if I had all of this for a user imagine if u I had even more let’s say reminders different lists different uh I’m not sure like likes or whatever so for all of these I would have to paste them in the same file well that would be in very confusing and very difficult to maintain to solve this issue we will be creating a new folder called routes and this folder will keep all of our routes separated so for example we have reminders routes so we will say reminders routes.js you can have let’s say user routes.js and you can even like have as many as you need and it will keep everything very clean and structured so let’s create these reminder routes what we need to do well first of all let’s go back to our index and let’s copy all of let’s actually not even copy but cut out all of these um requests uh with the command or control X let’s save this folder and go to the reminders route for now just paste it of course we will need to do some adjustments now but because it’s not going to work like that first of all we will need to import uh and it’s a different thing we will be importing router but also from express and router is what allows us to create these separated routes very nicely then we need to initialize this router like this so basically we’re saying this variable will become this router and now we can call this router so instead of having this app app we’re calling uh oh no no no we will be calling router.get router.get by ID router.create router.patch router.delete and I’ll show you in a second why because now we can simplify this uh whole thing a lot well first of all we need to export uh this not uh export this router that we just created and attached all of these routes to but now we can say that router dot slash uh without saying this reminders part router slash id then once again like this and like this so now it’s not yet finished we need to have one last adjustment so now if we go to our index file and inside here at the top we’ll import these routes so it’s called reminder routes and we are importing them from and they’re imported from actually it’s only one routes reminder routes.js so now that we can use these routes and we can tell our app uh instance to use them so let’s say we will say app dot use and we will say so now all of these routes that we are going to pass you here they will have a prefix of reminders and group them together and then we are passing this remind all of these reminders routes so now our application will know that okay if we are calling um reminders basically slash or reminders or just yeah reminders ID uh or whatever it will know that the prefix is like reminders and we don’t need to have all of them added here manually which simplifies the readability a lot a lot more and here you would do the same for let’s say user routes if to created them here you would say users and pass here user routes and once again it would work the same you would have user user/ ID and it would know which routes to call so now that we have this we can quickly go to our um insomnia and check out if it’s actually still working so if we call them like this we can see that they are still perfectly working and we simplified it a lot okay so we Yes we did all of this um Uhhuh yes yes yes we modified it and yeah here’s I’m explaining a bit more of what’s happening it basically appuse mounts these routes uh under slash reminders path so we it knows right away a lot cleaner where to go so now that we’re done with routes with very basic uh routes we will be getting into the meat right now and um it’s kind of important to uh know how to structure your application because if you just create all of the files or everything in one file it’s going to be a huge mess and when it when it’s a huge mess it’s going to be unmaintainable and you will not be able to create a functional maintainable uh and scalable application so usually you would select some sort of a structure to follow and most of the big companies uh right now and not only like also the small startups uh use this MVC plus service structure and um why you would use this I will explain once I’m showing but yes once again it’s called model view controller plus service pattern and it helps to us to structure everything so now I created this like analogy of a restaurant because we will be creating um three more folders so let’s actually do that first of all we will create uh controllers then we will also have the services uh not as a file i created it as a file that’s not good let’s remove it i need to create it inside as a folder so it’s going to be called services and then lastly we will also have models so now let me quickly with this restaurant analogy go over what it means so the controller will handle these requests and send back the responses to the user well you can right away understand that it’s kind of like a waiter in a restaurant so it’s the one that will take the order from the user which is a request it will pass this order to the kitchen to basically create whatever was ordered which the kitchen is in our analogy a service layer and it brings back the prepared dish which is going to be the response to the user this controller/waiter doesn’t process any data doesn’t prepare anything it acts only as an intermediary it doesn’t care really how the data is processed it’s only there to basically communicate uh this order then there is this service layer which is as I said is kind of like a kitchen inside a restaurant which is responsible for the logic and the actual processing of the data so the kitchen the service layer takes the order from the controller a waiter and processes it prepares the food based on the ingredients a model which we’ll talk soon about it can combine multiple ingredients into one and uh it can add specific processes like like cooking mixing garnishing basically all of the logic that you would do for um processing that data or creating that food happens in this service layer and then there is models layer which only communicates with a database uh in our like code example but in a kitchen example you can think of model like an ingredientre different ingredients to make those dishes so it doesn’t care how the food is prepared the final dish it doesn’t care about how it’s served it is simply a dish I mean a product and um yeah it provides essential components basically data to the kitchen which is service layer so that this final dish can be repaired so for example I need a tomato I’m taking it from the fridge and tomato in this case is a model I need some cucumbers I’m taking let’s say reminders and processing them and passing back to the waiter maybe this analogy will help you a little bit easier to understand like why are we separating everything so much and I will also have some examples for example when in the service we need different ingredients uh and we will call different database um tables so yeah we will see how this all ties up in a not a restaurant but in a coding environment so let’s continue so the first um actually the the first one um layer let’s say in our application will be the routes layer because that’s how we will know which route was called so it’s either reminders slash or user slash or reminders ID and then this router will uh specify which controller to use so let’s say let’s go here and let’s create our first controller which is going to be called reminders controller so if we go here um let me check if the stream is still good if there’s any questions or anything so far uh hey Aditia nice to see you here you’ve been here well you’ve been in Discord yesterday so today here very very glad to see you sir Josh uh hi please just join how do I get started please yes uh I see our team member valuable team member just posted um sent you a asset link so just download that and you can have all of this uh what I’m going through um yourself and then after the the stream ends we will post the stream on this channel so you can always come back re-watch at your own pace stop whatever we will never remove this tutorial so feel free to go at your own pace you don’t need to follow me uh like uh in real time let’s see what else uh Ji subscribed thank you thank you very much i’m so happy to see that you are guys enjoying at least some of you not sure if everybody but thank you very very much J uh okay I’m late today what uh we are building today yes we’re building a full stack application a very beginnerfriendly um application basically taking your first steps into full stack development and uh yeah I think we can continue now and um yes what I was talking yeah oh yeah creating those uh controllers uh let’s go to our controllers folder and let’s create a new controller so we will call it reminder controllerjs Perfect um so mean you could have here many different uh controllers so user controller I don’t know likes controller or whatever so all of them also will be se would be separated for us now it’s a good example with reminder and actually um yeah I will tell about it a bit later so now let’s create this controller first of all we’ll say export const and give the name so it will be called reminder controller and now we will inside it specify all the functions so in theory we will try to follow exactly uh let me close this user because we will not need it and actually I can even remove it now because we will not need it um okay we will follow this structure so for example we see okay we have get all reminders well okay that means we need to create a function to get all of those reminders so we will call it just like that get all reminders uh and it should be camel case so here like that uh this will get a request and response the same as we get here request and response and then we will specify what this function needs to do so for now we will keep it uh keep returning this later on we will add like all the data interactions with database but as you remember it’s not happening at this layer yet so we will simply uh have this response still get all reminders so if we save this we can now go back to our reminders table uh remind us routes I mean and then import this reminder controller so we would import it like this saying reminder controller from controllers reminder controller be very careful and add this add this JS at the end because it’s going to crash for you and now we can use it so we can make this a lot more simple so we can remove all of this boilerplate code and simply say reminder controller and call get all reminders that’s it it knows that if the user goes to this route which is reminders slash I need to call this function and that’s it nothing else and pass the request and response to it so we go here and you can go here by clicking command and on this or control on Windows and on the name and we see which function is going to be executed and what this function will do it will simply send a response to get all reminders okay perfect but now we need to do that for all of the rest uh functions so here we can see okay we are trying to get reminder by ID perfect let’s do exactly the same so maybe I just even will copy it and say what we need to do here is get reminder by ID and uh what is it complaining about oh I yes I forgot to add this comma here we need to separate them basically okay now we’re getting uh yeah the response will be this one so we can copy it from the get we can go to our controller and paste that we know that the response is going to be exactly the same and now we can simplify this as well very easily reminder controller get reminder by ID okay saved let’s go quickly create the rest so it will be I think it’s called yeah create reminder we get request and response and in here let’s see what we were doing we were returning create reminder response so let’s paste it save it go to our routes remove all of this boilerplate code now leave this one say reminder controller and create reminder last one not last one before the last one is to patch so we will create One more okay like this we will say a sync and we will call it update reminder we will take request and response and we will return let’s see what okay we’re returning this one let’s paste it back and then we can very nicely once again apply here reminder controller dot update reminder and now it’s the last one so let’s create quickly a sync we will call it delete reminder request and response and then we will have response send and delete all reminder and lastly just say delete reminder perfect let’s save this let’s save this now we can go to our once again insomnia and we can and we can uh test it out so let’s say if the lead is still working okay they are still all working amazingly just as before um yes so let’s see what we need to do next we created all of these reminders uh all of these functions i mean we are using all of these um controller functions inside our routes uh and now we say yeah basically I’m telling here what we’re doing so feel free to read it out um so now it’s time to actually handle some data from these requests because in many scenarios we will need to get uh the ID for instance when we are creating when we are updating or deleting uh a reminder from the URL or maybe we will even need to get some data from the user so for example when we’re creating a new reminder we need to get the actual reminder and the notes for it so we need to somehow get this data and to do that it’s actually very very easy well what we need to do is we need to get it from the request then all every request will have this params and then the name of the parameter that we are passing in that URL so let’s see how to do that look for example in the get get reminder by id and also I’m here parsing to int because if you know like all of these um are passed like ID not like this but one two they’re a string but we need to convert them to a number in order to actually pass them to the database sometimes databases also store the ids and strings so you would not need to do that but for us it stores that in an integer in a number so we need to parse it to an integer as we are doing here so if we go back we will say here uh const and we will say what the the name of this variable so we will get call it reminder id and as I said we will par parse this id to integer and then we will take it from the request so from here and in the request there will be parameters and we will okay so how is the n what’s the name of the parameter so if we go here and we check for get reminder by ID we called it ID okay so that means we can copy this come back here and say that request parameters should have ID and in order to test if we are actually uh getting back this ID we can a little bit transform this and add these different quotes under escape i’m not sure how they’re called and we say get reminder by ID and we specify with this syntax of inserting this variable uh reminder ID so now if we save it and go to our insomnia we say get reminder by ID and uh we pass the ID one if we save it we get ID one if we say let’s say ID5 it’s working perfectly that means we are getting this ID we’re parsing it and everything is amazing from the URL part you could pass many different URLs so you could have here uh also like ID and then um name and u yeah like different names but you would get them exactly the same like request params and then the name of the parameter that you passed okay so this is working for the ones that we need to pass the reminder so we can copy this and do the same for the update reminder because if we remember for updating we are also passing the ID and we see that for delete we also pass the ID so we can pass the same thing for delete but now for create it would not make any sense to pass all of that data in the URL first of all it’s not secure at all if we would say uh here let’s say like uh reminder and then pass like everything embed inside the URL and then take it like this no no no no very bad so we have a way better way of doing that and we can pass JSON format to these requests so to to achieve that uh we will need to of course have some uh changes and I talk about the change um well first of all maybe ext let’s extract this URL and then I will say what we need to do but actually extracting this URL is very very easy so in create reminders what we would do is we would say um let’s create let’s say new variable called reminder and we will take this reminder from request once again but now we will not take it from URL parameters but we would take it from the body of the response of the request and then we would say the name of the variable that we passed so in our case we called it in the database as you if you remember reminders so if we go here and u let’s reload where’s the reminders table yeah here we have the reminder and we are expecting that to be passed when creating a new reminder so now we can simply console log this reminder right but let’s see what will happen now if I do that so let’s say I go to uh create new reminder and of course I pass this so we need to pass it as a body we will pass it as a JSON body and I’m saying okay so I’m passing the reminder and the reminder would be uh take the dog out for a walk i don’t have a dog but I would love to so yes let’s see what will happen i send it and I get um I get an error cannot read properties undefined of reminder so why is that happening let’s try to console log the whole request body so let’s now have it like this go back call it go back here and see the console log reminder is not defined uh and um oh here let’s say request send like let’s do like this go back send this request and we can see that request body is undefined but why is that well um express doesn’t parse the incoming data to JSON by default so we need to enable that by like basically passing the the middleware and the middleware ware it’s also um yeah let’s say what is let’s talk about what is middleware in general middleware is kind of a helper functions that help you process the requests before they reach the routes so for example a request comes in we process it here and only then we pass it to the routes if like the middle it passes the middleware but it can throw an error inside it it can perform different checks and we will even see how to create our own middle middleware a little bit later but for now we will uh add a new middleware that will that express provides to us and it’s going to be the app like how do you apply it is simply app dot use and now we need to say which middleware to use so we’ll use one from express and we’ll say where we want to use the JSON middleware what this does is it parses the incom incoming request to JSON uh which will help us to make this defined basically and uh let’s try to save it and try it out right now so if I leave it like this I can even do like this and go back here i send the request we can see the reminder of take the dog out for a walk that means everything is worked because as you can see now it parsed this um this uh body into a JSON file that express now knows how to read and know how to return to us so we can use that so if I would say let’s say pass here also notes and let’s add something like don’t forget to feed him before and let’s say I pass it go back here we can see that now it has a reminder and a note and I can pass even more like a lot of them so um okay now what else let’s see let’s see our um guide and maybe we’ll answer some comments yes here I’m explaining like how to add the middleware what is it and here we will go into service layer so before that I think we can take a short break uh sip some water and check out some of the comments yeah I see Danielle said it’s important to stay hydrated so I’m trying uh Jade thanks for the MVC plus services no worries no worries i’m trying um I’m trying my best hopefully the explanations are also clear enough enough i think my back end will be much cleaner after this hopefully hopefully you can use a number uh which will enforce to be only number any char will throw an error yes that’s also possible yeah uh so uh what what’s next i think uh oh Adita also commented great to see awesome content thank you very much Aditia appreciate you a lot always supporting always here uh yeah very very much so let’s go back to coding right so now we will be introducing the service layer and here you can also right away see what is this service layer i already explained it a little bit more inside um like my restaurant analogy which hopefully was good enough but basically a service layer it will contain all the logic of the requests to like yeah I’m doubling down but without let’s say analogies uh it will be responsible for performing the operations on the data and coordinating everything between the model and the controller it’s basically a layer in between uh model and controller which is the main logical part like where you would do calculations and stuff like that and here I’m listing some of the responsibilities as well like will perform core logic coordinate and aggregate the data with different models so you can call different functions in a model like get something then update it and delete it and uh yeah so it will also interact with the third party services or APIs and return process data to a controller so it’s a very important layer and some of the um applications skip this layer but and do let’s say all of that logic inside a controller i would never do that and more most of the more let’s say modern and um bigger corporations will always have the service layer because it makes everything so much cleaner and so much structured uh a lot more reusable and uh it’s a very good practice to learn it and always use it so yeah that’s that let’s see how to actually implement it and add it so first of all as we can see here we are we need to create actually we already created the services uh folder but inside here we need to create our reminder service so reminders service.js okay and now here let’s create um let’s say the functions that will be responsible for doing all the logic so let’s create again let’s say export const and we say reminder service and then we do like this and um here we can all like specify and define all the functions that’s the word I was looking for a sync we will have get all reminders so if we get here we see okay we have a function to get all reminders that means we will need to get all reminders And uh it will for now not get anything and inside here for now let’s just leave some comments and say fetch all reminders and for now let’s because we don’t have yet the model which will interact with the database let’s return only an empty array and let’s continue creating for all of them and in theory you can just copy paste to make it faster for you but um yeah because you asked I will uh do it like this get reminder by ID and actually maybe it doesn’t make sense to waste the time on this basic uh implementation um just definitions basically so fetch reminder by ID maybe I’ll just go here and copy the rest so we’ll have the create reminder update reminder and delete and once we are adding some logic inside there I will uh keep on writing because here we simply basically copy what we defined here the functions as well so not to save some time and leave some energy because it’s already getting late for me to explain let’s say front end as well a bit better let’s do it this way here now i hope it’s not going to be a huge issue for you guys so yeah now that we have this service layer um we need to connect it with our controller layer and now we will be start adding uh proper structure and final structure almost final except for the errors of our um controller functions so all of the controller functions will have this try catch block because we need to try to execute this function that we will pass but if it fails controller is responsible as a waiter let’s say if the cooking is bad if it I don’t know if we don’t have this uh ingredients the waiter is going to be the one who will come to the user and say sorry we cannot prepare this for you it failed because of something so yeah that’s why we are having this in the controller because it’s it’s talking with the user so first of all we will try to actually get these reminders so we will say const reminders and we will be calling the reminder service but to do that we also of course need to import them so let’s do import and then we say reminder service from here that we just created once again if it auto corrects add the GS at the end and now we can start uh saying reminder service and we want to get all of these reminders so if you get them if everything is good let’s return response the status and the status codes we will also talk a bit more uh about them later but probably you heard about like 404 200 500 uh there’s different status codes to communicate what uh error was it so for example if everything is good 200 is okay that means everything worked out and we’ll return the status 200 and we’ll return the JSON of these reminders so that means everything worked out but if we got an error we will need to return the status of 500 for now we don’t know what was the error so we will simply send 500 error which is like a very general internal internal server error so what a uh mouthful so we’ll say here as well internal server error and we will see later on how to make this a bit better so now that we have this we need to apply this logic for all of our routes so let’s go and do it so here again try catch block we’ll be trying to get the parse the ID and we’ll be trying to get the reminder by which by ID so we’ll say not controller reminder service dot get reminder by ID but now we need to pass the reminder id for our service layer to know with what ID should I call the models should I call the database basically so we are also passing down this ID and then we are if everything is good we are returning just the same only changing what we return which is reminder and not like all reminders but the error for now will be exactly the same we can remove this uh basically if it didn’t work uh just call it with internal service error let’s do the same for create reminder and in here we will need to uh get the body request but now we like it would be a bit un um how to say redundant to do it like this notes and say okay give me notes it’s not a very good practice it’s not let’s say maybe horrible but there is a lot of a lot easier way and also we would not be extracting in this layer because we’re trying to keep it uh very um clean so what we would do is we would again call const reminder and then we will say reminder service uh create reminder and we would pass all of these um all of that like JSON body which is request slashbody and it will contain all of the data from the user like a reminder user ID and notes and we pass it to create reminder and then create reminder we will define the logic how to handle this so now if everything uh worked we’ll return f 200 if something failed we return 500 and we delete the rest there so now it’s actually uh these two are very similar to update uh so let’s add this try catch block let’s try to parse the ID and let’s try to uh call um yeah const reminder and we will be calling the reminder service dot and it’s update reminder and we will be passing the reminder ID and for this is going to be a little bit different because update reminder well we need to know which uh which object are we trying to update so we need reminder ID but We will also need to ask the user basically for him to pass us the updates that he wants to do so if you are updating the reminder itself let me know what what text should I change it to if you’re updating the notes let me know to what you want to change it to so what we will do is we will also pass the request body the same as in the create reminder because here he’s passing his initial basically reminder data but here we’re passing already the updated so if we go to insomnia and to update reminder we would also have exactly like this so reminder and then something like new reminder and then in the J in that oh we don’t need this in that JSON we would get this reminder and if pass it to the update reminder service so if everything is good return this if something went wrong return this and lastly for the deletion it’s try catch and then having this here and then lastly calling the con reminder and calling reminder service and where is delete reminder with the reminder ID of this okay like this and like this yeah I’m actually not very clear like clean with keeping these here so it’s not an error it really depends on what your team is which pattern your team is following you might not be adding these uh you might be adding these these do not change your code logic in any way so yeah it’s really up to the teams and we can also remove this one so now that we have our controller basically almost completely done we will change the errors we can continue and check out what we are doing next so we updated all the functions in the controller uh yes we talk a bit about here now controllers don’t have any logic and don’t handle any logic they only call services so now it’s time to introduce the model layer and the model layer as I talked in the my analogy it was it’s kind of like an ingredient like a product it represents the data layer it it is responsible only by to interact with the database basically it only runs the queries u to store update retrieve or whatever here is the place where we will define our raw SQL queries and as you can see the responsibilities would be to interact with the database and this like a prov provides a layer of abstraction which is basically I only what it says I only know how to interact with the database don’t give me anything else you call me I give you like the result back that’s it so this way we can reuse them very easily so for example maybe even in user uh control user service I would need to get uh somehow some like for some reason his um one of the reminders so I could call this find by ID um or even get all from the user ser uh service and uh or even in the reminder service I can call multiple of them so for example maybe I need to get one reminder by ID and then maybe I need to check if it exists that’s actually what we will do and then maybe I need to delete that reminder so yeah this is uh what it’s the model layer is responsible for so let’s do all of that so let’s go back to our code and inside the models we need to create a new model which is going to be called reminder model.js so this reminder model uh we can start defining the um the queries itself so let’s first of all import the database because as I said here is where we will talk with the database so we’ll say config database njs very important then we will say export const and we’ll say reminder model and it’s going to be uh like this so here now inside we will we can specify all of the functions so first of all it’s going to be get all and in here we don’t need to pass anything it’s simply going to call the database and return it so first of all we will say we will store the result in this variable and we are calling the database so DB dot we are passing this query to the database and now we need to specify what query so first of all we will say we want to select everything all the fields basically uh like uh the reminder the notes the user ID everything from uh which table so we have two basically you could even either specify reminders or user or if you have created more tables you will tell here pass the name of the table so basically what you have here okay we say take all from reminders and uh that’s it we only need to get all by reminders but we also want to order them so basically to return them in order by how recent they were created so we want the most recent reminders to be at the top maybe you want a different order that’s also totally fine but for us that’s what we want so we would say return where ordered by created at in a descending order so now this will uh like this will be the the query uh SQL query and we would simply return we would call this database we will try to get all of this and we would simply return uh all of the rows from this result so no no no so we’ll from this result we will return all all of the rows because that this will always return an array for us in this case we want an array later on we’ll see what to do if we want only one object so now uh if we try to do get all we will not get anything just because we still didn’t connected it to our services but soon we will do it we still need to define some more functions so one of them is going to be find by ID and in here uh it’s going to be a bit different because we are actually going to get the ID because we want to know on which ID do we need to do the query but the rest is going to be very similar so it’s going to be result we’ll say DB query and here once again we will follow very similar pattern we will select all fields you could specify here let’s say what field does reminder have like only the reminder notes so we could say reminder and notes uh and then you would follow something like from but for us we need to return all of the fields so from reminders table uh actually here I forgot I removed it because I already see we need to get all from reminders table so yeah here we select all from reminders table but we need to get only where this ID like we give the name of this field so we say where the ID of that field is equal to um this weird syntax to basically we’re saying to the value at position one but now we need to also somehow pass this value in theory you could have added in here something like this uh of course by changing this but it’s very unsecure because of SQL injections so this it makes it a bit sec more secure and how we would pass uh the values we would simply say here so the value at position one later on now actually when we will be showing the create one you’ll see how we can pass more more uh fields more values so now just simply return uh not const but return result dot rows but as I said we are returning again an array but in this case we should expect one object not an array of objects so we would simply take the what we’re saying here take the first um object from rows array so why it’s not one it’s because that’s basically how programming works and we count calculate count everything from zero not from one so zero means at position one means at position two and so on so start counting from zero if you’re yeah total beginners get get start get you uh start getting used to that that’s what I was looking for okay now let’s do for create so we create once again a create function and in here we will once again say const result equals DB query and we will specify select uh actually not select because now uh now we are inserting now we are like creating adding new data so this is going to be a bit longer and um let for that let’s make it um structured let’s say a bit better uh but maybe let’s write first of all in one line and then I will structure it so what we will say we are inserting now not selecting in so now we need to specify instead of from we will need to say into which uh table so we are inserting into reminders table and now we will say um what values are we inserting basically so we specify the values like this it’s going to be reminder just as we have uh where is it in here reminder notes and we can also pass uh in here the user ID which we actually need to do so reminder um notes actually notes and then the last one is I said user ID and the names here once again you can get like they should match what you see here at the top so now that now that we defined these um what we basically need to insert we can also specify uh the values itself so it’s going to be similar to kind of this but a bit different now we say okay so insert values so this value is going to be at position one and then the notes will be at position uh two and then the last one will be at position three and after you do all this query please returning returning please return me everything here you could also specify as I showed you here what to return but we need to return everything so now how do I pass uh the values in here well it’s following a kind of similar uh actually exactly the same pattern as here so we give comma we open an array and now it’s the the the order is going to be very important actually first of all we didn’t even like get these so we can dstructure them by saying that give me a reminder because as if you remember in our insomnia when we’re creating we will pass the reminder the notes and stuff like that which are going to be required so yeah we are passing the reminder the notes and lastly we will pass the user uh ID and as I said the order in which you pass here the the values is very important because if we say here let’s say notes reminder and then user ID and actually it I think it kind of makes sense right away to u make it a little bit cleaner and to do that I will need to change it to this and also okay so insert into reminders with these values and then return me this looks a lot cleaner so it’s a good good thing always so yeah what are we doing now is we’re saying notes because we said here that the reminder will be at position one so now it uh it means that notes will be applied to reminder that’s why the position in which you pass here the fields is very important so we actually meant that the reminder should be at position one just as here the notes will be at position two so let’s do like this and the user ID will be at position three so we are passing here the user ID and um yeah that’s how you insert something but now that you insert it we also need to return the the item that we just inserted so we’ll say uh return result dot rows at position uh zero just as we had here and lastly is the delete so it’s going to be a sync delete and we’ll have here again we’re only going to be asking for rem reminderinder ID and I already see the issue a sync reminder ID and in here we’ll be specifying once again our uh query so we’ll say await actually I didn’t add it here as I see anywhere a wait and it’s very important to add that so because we need to await until we get the result and only then return maybe there someone even commented this maybe let me check uh nope one uh Muhammad following from Dubai oh that’s very nice that’s very nice so yeah this is very important to this little keyword to await or underway to just wait until this query is executed and only then return so we need to do that for all of them uh await await we would have spotted this issue later on but yeah I’ve I’ve seen it here so now we say the B query and let’s define uh I think it’s not the last one because I probably I need yeah I skipped update I think so but the delete will be um something similar but with a different keyword so we will say delete from once again now we say from which table to do we need to delete it from reminders uh whoopsie and then we will need to say where ID equals it’s like updating a one once again when you’re just starting out you can try to write these queries with the help of um CH chat GBT just ask what kind of um what kind of uh query would you like to build and it will return you like all of this you can even join the tables to like return different things so it’s um yeah it can help you very much but now once we delete we simply want to because now we deleted this item we simply want to return the result and the row count of um the deleted items basically how many were deleted okay and yeah I skipped the update so we’ll say a sync update and now we will be again once updating we need to get um the the update values but this is going to be a bit different because we are going to be patching so I’m not sure how to show you so for now maybe let’s leave update implement later because it’s going to be the only one that’s kind of different in a way that we will not specify the query here and I’ll show you later why is that but yeah now that we have all of these created let’s see what we need to do and yeah oh yeah here you see how it’s going to look like but I will not add it yet i will explain to you a bit later so now we can add these models and start using them in our service layer and um to do that uh actually let’s do that let’s do that yes so if we go back to our service layer here we can import the model uh in here we just go import yes reminder model and also don’t forget to add.js and now let’s start using them well first of all the yeah the first one is going to be very easy we don’t need to pass anything we don’t need to do anything it’s simply return reminder model get all and we get all of these uh reminders and return them right away for reminder get with ID it’s a bit different because if you remember from the controllers when we’re getting by ID we’re passing this reminder ID so if we go to the service we can get this reminder ID from here that we received and now we will say okay so I will assign this reminder and I will await again it’s very important to wait for the response and I will call reminder model find by ID and I will pass the ID so I will pass this reminder id to the model so if I go to uh find by ID we can see that it is expecting the ID and that’s how we will find so let’s go back to the service and if now we need to check if there’s any errors so if I for some reason this reminder is not returned that means something was wrong something did not work out so what we will do is we will throw new error and we need to specify what is this error so for example a reminder not found because we let’s say did not found the reminder something is bad and we will throw the error but if we found a reminder we will simply return it and um yeah and we will return it now soon with the creation after we implemented this we will see everything in action with insomnia so now after create uh after getting it by ID it’s time for create implementing the creation of the reminder so if you remember from the controller uh we are passing the whole body to create reminder so in here we can get this object of reminder we could either destructure everything inside here and take all the values one by one or you can have something like const and in here specify what we are receiving so if you remember we’re expecting the reminder the notes and also the user ID the same if you go here the create expecting reminder notes and user ID so actually yeah here I showed you how to dstructure them inside the uh when we’re receiving here I will show you maybe then a different approach uh how you could do it so and actually I’m doing that right away uh so doing this way and what this does is basically instead of having const reminder and then equals new reminder dot reminder so it would be even wrong maybe something reminder object so it’s and then you would have something like this for notes and here notes and then the same for user ID it requires three lines of code that would be imagine if you have like a huge uh form of 10 inputs getting all of them like this is it would be a nightmare so what we’re doing is instead of assigning them each to a new variable or of course you can have it in here and pass it just like this uh as well to a function without assigning to a new variable so for example if let’s say we call what function do we yeah create so we say we create this uh const created reminder and we need to call the reminder model.create so you could pass them like this one by one and then reminder notes but it still doesn’t change doesn’t change the fact that it’s very long so we can destructure all of them outside so what we’re saying here from this reminder object take out these values so it’s very important to have this curly brackets around here and now we can use the them right away without doing them like news reminder new reminder notes and repeat ourselves we can simply say reminder notes and then lastly user ID so it right away knows like okay I’m taking these values here and I’m passing them so it saves us a little bit of time uh yeah so I highly suggest you doing that in theory you can also as we did inside the model do them right away in here you don’t even need to have this line of code so there’s a lot of um ways to do it but just know that do not do new reminder reminder new reminder notes new reminder user ID choose either this one or the one where we d the structure right away inside the function okay okay so now that we are calling this we uh need to return it here but also um as I told this and I want to show you as an example this service layer can have a lot of different things like you can clean your uh inputs you can do a lot of different calculations so just to be a little bit um show a bit more of an example I’ll do let’s say it’s common to sanitize the input form so for example let’s call const sanitized uh reminder and what does it mean is we’re cleaning up the user input so for example the reminder user can pass us like something like this space space space space hello space space space and maybe we don’t want that uh we can very easily sanitize this and clean it up we will say if the reminder is passed just trim it and trim means means clean the empty spaces before and after let’s do the same for notes maybe we don’t want to have like that many spaces at the start and at the front it just doesn’t make much sense for us in our case let’s say so we’ll say trim and this question mark means uh if it exists kind of so if it would be null and we would call uh trim on null it would crash but now this prevents from crashing and lastly uh for user ID think for user ID we are simply passing it as it is like that so now instead of passing them like this we can pass them as sanitized basically cleaned up uh versions so yeah this is not necessary i just wanted to show you that you can do a lot of things in the service layer you can have a lot of different logic you can have here running like I don’t know huge for loops and stuff this is where it would happen so yes um if everything is good here we are returning the the the reminder we can also have like this error handler here saying that if create reminder does not exist something like something crashed in this case actually our controller if something would crash still catch it so we don’t really need this check here and here we need it because if the reminder was not found we need to be clear with our error but here when you’re creating a new one it cannot be not found because it should be not there yet if you know what I mean okay so for updates um are we yeah probably let me actually first of all showcase you how we create get and get them by one by ID and then get all of them and then maybe I can show you the update because that’s going to be the most complicated one so if we go back to our insomnia first of all if we try to get all reminders let’s check that we are not returning anything so we’re returning only an empty u JSON so if you remember we changed it in the controller layer and now we’re returning a JSON it’s no longer uh we’re no longer returning the response send and here like some HTML code we are right now returning a JSON of the reminder but because we don’t have any reminders it’s empty now so now let’s create a new reminder so we will add reminder uh take the dog out for a walk note the same one and let’s check the id of the user so the id is one so we also need to pass the user ID and for now we don’t validate this data in any way but later on we will add so for example for now if I would um not provide something it would not crash it would crash but in a let’s say database layer model layer so now if I say send we are uh not receiving uh oh yes we should post that’s good uh if I go to reminders we can see that the reminder was created and sorry and we can see that the data is exactly the same so we are reminder is take the dog for a walk the note is don’t forget to feed before it’s not completed the user is with an ID one and it was created so now if I would go to get all reminders and send this request for some reason it’s not working so let’s see uh what’s bad here so if I say get all reminders reminder service get all reminders and now get all select everything from reminders order by created at descending okay let’s console log the result here uh console log result and let’s see why is it probably I’m missing something oh yeah let’s do rows okay let’s see let’s see it actually it has it in here I return it okay so in the service layer okay Maybe uh where is it and it is in if yeah in service layer okay so yeah I already no actually I don’t see the error because we should be returning all so now if we go to controller let’s see here if we get console log and let’s see if we get those reminders the probably it’s a Oh yeah here it’s a promise but we are uno so yeah probably I’m missing something like crazy small okay so is it Yeah let me check the controllers real quick yeah I already see the issue and it’s right basically saying me here we are even though we are calling here like a reminder we are not awaiting for the response so we need to wait until we get the response so this is a very important thing and only after we get it we will return it so add it for all of it await and that’s why we also when creating did not receive it so sorry for missing that in so go to reminder controller and for every part where we call uh our service layer add an await before it so for example now let’s test it out if we go to our insomnia and if we go to create new reminder and let’s say uh buy milk and um hello for user one if we create it yeah we are also receiving it back so that was my first hint because I was a bit also confused why didn’t I receive it but now if I go to get all reminders I will get all of my reminders There’s and even so for example now I can say okay I have reminder with ID 1 and with ID two so if I go to get reminder by ID and say give me with ID2 it will return me a reminder with ID two if I say with ID1 it’s a first one but if I say with ID that does not exist it will throw me an internal server error but we will handle it a little bit later properly so um okay what’s next what’s next so now we need to see how to update it and actually update one is going to be the most complicated because uh we we need to get basically okay we need to allow a person to pass only certain uh fields so for example if the user is updating only notes field it should update only notes and do not touch the user ID or completed or um even the reminder itself or if user let’s say completes a task uh so we need to update only the completed field we don’t need to update the notes or the reminder fields that’s why in here and me I do not specify too much but in here that’s why we are building this SQL dynamically basically so we have we’re taking all the fields from object keys with new values and keys will so maybe actually let’s try to write it and then I will console log it with it will be a lot more easier for me to explain it well so now for the update reminders we can go to the service layer and in here start implementing it so the first thing that we will need to do is once again get all these values so I would say here const and the values that I can get are like the reminder the notes and I think it’s also completed nothing else i cannot update the user ID and nothing else so only these three values and I will get them from the new values and later on we will see how can we define the schema of what we should allow to pass and what is required what’s not required we’ll see it very soon so now that we get like these values we need to according to them build our SQL query dynamically so first of all we will say const and we will take all the fields and we will say object dot keys and let me first of all write it and then I will show you so new values if I console log these this uh fields actually it should have been let’s save it and let’s go to update reminder and pass let’s say yeah new reminder so if I pass it here and go check it out the fields are basically these so I’m saying the reminder notes and completed I’m taking the key and putting them as a name so for example let’s try to pass the notes as uh notes and saying here uh updating note yeah I made a mistake but it’s not a problem um actually I’m getting some sort of updating note okay let’s make it the same let’s try to send it yes it fixed it so now if I go here I say okay so the keys are reminder and note this is a key basically the name of this will be a key uh basically here this is a key here is also a key okay so now that we have these keys we need a way to get um also the values not the keys anymore of this object so what we will do here is first of all we will uh call const and say values equals object dot uh values and we will pass the object that of the values that we want to take so and maybe also actually let’s do it like this after the this one and after this let’s console log but here fields so now if we go and call this and go back we can see that okay the key is the reminder and the notes but the values are the new reminder and updating note so actually the values are the this part uh and basically what this object dot does is it takes the object and makes it into transforms it into an array with either like keys or values so now now that we have these we need to a way to create a set clause and a set clause is um basically when you’re updating you need to say okay so actually I think I have an yes we’re saying update reminders and we need to explain what needs to be updated like what needs to be set so to do that we can go back to our code and to reminder no no to the service and we need to create the set clause so to do that let’s say here const and say let’s call it set clause equals and we will say fields dot map so we’re mapping through all the fields that we pass so you it depends on how many you passed maybe it’s only reminder so only one or maybe it’s reminder notes or maybe it’s only completed but it will map through all of them and mapping it’s mapping it’s kind of like a for loop uh a bit different but in yeah it’s mapping through all of these items taking first second third and doing something with it transforming it so what we’ll do is we will take the key so the name like reminder note or which is going to be here and then we will take the index and at which position we are uh in this so this will be at position zero this is at position one and this is at position two so this is going to reflect that and we will transform as I said in this map so we need to open this like under escape quote and we will need to say okay this is where I’m going to pass the not a string because if I would simply say here key it will act as a string but we need to say that we here we’re passing a javascript expression so we’re taking this key so it’s going to be a reminder and then what we need to do is we need to say equal and if do you remember how we in the models how we did like where id which is the key that we’re trying to do and we need to pass the position of it so where the position is one or even here a position is two three and it can be four five six seven so what we’re saying here is if you remember this is the we need it in a string because this is how it’s done here and then we are need to open the JavaScript expression so this is no longer a string this second dollar sign and in here we will say where the index uh and plus one because if you remember I said like it start counting from zero but here we need to start showing from like a normal person one two three so now we created the set clause and why this set so we can console log it and actually I will show explain you why is it important to do it this way so if we go to insomnia let’s call it once again open it up and we can see that this is the keys this is the values and this is the actual set clause so we’re saying okay literally exactly like here we’re saying where ID is at position one but here we’re saying where reminder is at position one and it notes at position two because we don’t have the user we did not add here and you kind of already m can guess why we do this thing because user can pass only one thing only two things or all of them and we need to dynamically know uh build this set clause because if we would add there uh let’s say uh set and pass them all by one so uh let’s actually build this query and then I will show you so con query equals and then we open this uh query and then we’ll say so in this case we’re updating the reminders table and here we will be passing this set clause and here we need to want to pass this set clause and uh again we want to specify the JavaScript expression inside it so this is the syntax for that we’re saying set clause and we want to also be because now it’s an array we want to transform from this array into a string so we would set set clause and join every item inside an array with a comma so I can actually even consolate log console it for you to see so we would say set clause and join all of the strings inside this array which is in this case this one so this is first item this is second item join these items by a comma so if I save it send it go back here we can see that now it’s a string and they are joined by a comma i could say join them by this but of course it’s not going to work for us because um yeah and you can see it’s joined like this but it’s not going to work for us because this is what SQL is expecting to be separated by a comma or let’s say here like this okay so now that we have it uh like that what we yeah so we are setting set clause and we want to specify which object to update so what we will say and to which values to update we will say where first of all uh and I actually actually forgot to add one more thing because here we will say where id so we are saying which object to update and we will say where id equals and we could either again inject it in here like this uh say like the ID reminder ID but it’s not secure it’s prone to SQL injections so that’s why we will do a little bit different and after we add all of these uh values basically to um to the values that we will pass so reminder text like this reminder no uh this new reminder update note at the end of it we also want at the end of this um array we also want to add the ID of the reminder so let’s quickly run it again and see how it looks now so now this looks um yeah actually values I’m not console logging uh here no wait let me clean it up here we don’t need anymore set clause we don’t need anymore to see fields for now like this so values push and then we are adding the rem no reminder ID okay let’s save it let’s send it let’s go back okay so now we see that the values are new reminder the same as we passed here then updating note and the last one because push adds it to the end of the array is going to be the reminder array the reminder ID from here so for example if I add two here and go back it’s going to be two okay so now we will say so the ID of the object that we want to update is again this little uh syntax but now we also say that okay now this is going to be an expression it’s going to be you could either do values and at position uh values dot length so it’s taking like from the array of values so from 1 2 3 we would say and because the length of this is uh three so actually let me console.log yeah this I hope is not over complicating things to you but we need that so if you console log you see that the length is three three and we are saying that take give me the at values at position length three but let’s see what will happen if we do that uh so I console log I do here and it’s undefined be why well because here the length is actually three but if you remember we are starting to count from zero so you would need to add minus one so now if you do this the will be the ID of two but there’s an easier way to do it so what you could do and that’s also another helper uh we could say simply where values dot so actually let me first of all maybe even console log it it would be easier uh length so if I do values dot length and I console it log yeah it’s going to be three but um I I think it it should work um so basically what I want to do is take the last item of the uh of the array so let’s leave it for now with this approach but um later on we will check it out i think it will work minus one so now we’re taking the last item and this is going to be the the last item we always know it’s going to be the reminder ID so where id is this and then don’t forget that returning we will return everything there so now we have actually built um query so now let’s console maybe even log it a dynamic query that will change based on the it based on the inputs that we pass so now the quer is update reminders set the reminder at position one notes at position two and we know that the values so we actually also need to console log the values but the values would be that at position one we would have a reminder and at position two we will have notes so now if we let’s say pass only uh notes only reminder if we go back we are seeing that okay so set reminder which is at position one and um yeah the values at position one is is is a new reminder and the same like basically as we say here so it’s taking the new reminder yeah so it’s a little bit more complicated than the the rest and I hope I like I managed to Uh I hope I managed to really explain it well because it’s it’s going to be the most complicated one and but yeah but now that we have this query and these values that we want to add so let’s remove all of these console logs that we will no longer need we can pass um so basically let’s do const and then we will say updated reminder not update but updated reminder equals and we will say await very important not to forget reminder model and here we will say update but now to this update we will pass the query that we’ve built here and also we will pass the values that we’ve built in theory you could build this query inside the model and it would it would be probably like still good way of doing it but I wanted to keep the models like very very low level no logic so it really depends on the team where you would do this uh building this query uh but um yeah neither one of these choices would be a bad one in the model or in the service in the controller that would be bad so okay we are doing updated reminder and now we’re saying if we are not receiving an updated reminder we will throw a new error so we basic basically throw new error oh error and it will be saying reminder not found because probably we did not found the reminder that you are asking me to update but if we found this reminder we will simply uh update uh return the updated reminder now that we’re done with this we can go uh inside our model of update and implement this model as I said we’re skipping it now but it’s going to be very e easy right now because we are taking the query and the values as we’re passing here query values and we simply need to call the database so basically say const uh result it will be again await db and then we’ll say we’ll do query and then the query will be very simple the query that we pass here so basically the the one that we’ve built here and the values as we were passing them uh in here as a second parameter the values is also going to be an array of these values which is what we need so if we go here uh no here we are going to pass the values here and now last thing to do is return the result and the rows at position one so now if the update is done we will return it so now we can try updating it so for example let’s try to get all reminders uh the first one is buy milk and the notes is hello so if I go to update reminder for two let’s say the notes notes is don’t forget eggs so if I update it I already get the second one where the reminder stays with like milk and the notes is don’t forget eggs now I don’t can update also the reminder itself uh saying by cheese and it will not update other values because if we would have not created the set clause if I pass only the reminders it will set everything else as null because I’m not passing notes it would set notes as null completed it would set as null so it’s very bad way of it would be bad way of doing it and maybe if we have some time um I will I will showcase but probably will not have time for that anymore because we’re whoa quite a lot long time in okay so now that we have this um this update service uh done the last service that we need to implement is actually the deleting service and do we have the controller for delete yes so this is also going to be a little bit different uh because what we need to do here is we need to check for a few cases first of all we need to check if the user can if the user that is trying to delete is actually the one that created this reminder if not we should not allow him to delete second thing is we need to check if the reminder that we’re trying to delete actually exists and if the reminder like the deletion was successful so first of all uh because we right now don’t have any kind of authentication we don’t know the ID of the logged in user or of the user that is trying to do the request so right now we will simulate it by saying authenticated user ID and we will pass the ID of authenticated user let’s say that is right now so first of all that we need to do is we will check if the reminder uh is actually exists that we’re trying to delete so first of all we will call reminder and now if you remember I told you that why are we separating all of these in separate uh like in the model it’s because now we can reuse everything so for example now I can say reminder model and give me this reminder with this ID i could call a lot more functions like other model functions in here and it makes everything a lot cleaner let’s say and more scalable because I could say okay then let’s um if we were trying to delete but it was it failed let’s update it maybe some field that um say that okay this user I don’t know like it’s it’s up to the um up to your client how he wants to handle but what I’m trying to say you can call a lot of different models inside these services so now that we got this reminder what we need to check is first of all if the reminder exists so we’re saying if it not doesn’t exist so this question uh exclamation mark says that if the reminder was not found if it’s not here then we will throw an error so we’ll say throw new error and then the error will be let’s something like you are not authorized okay if the uh oh no this is not I mean reminder not found yeah so I if the reminder is not here that means the reminder was not found based on this ID okay let’s move forward now if it find if it managed to find this reminder we need to check that this reminder and the user ID so basically if we go to our console if this user ID so it’s very important to have this exact same name if user ID is not equal to the authenticated user basically the one who is do trying to do this request then we would say um again throw a new error and here we would say uh you are not authorized or something like this okay but if the user actually the user ID matches um this authenticated user ID that means we can allow him to remove it so we would say we would call like as always const maybe let’s call it now row count because now we will be receiving the number of rows deleted so it’s a more appropriate name so we’ll say await and then reminder model delete and then we as we if we go to this delete we can see that it’s expecting the reminder ID so we can say here let’s pass this reminder ID to our model and now that we pass this ID we can check like another last check if row uh this row count is equal to zero basically it did not delete any uh reminders we can throw yet another error saying that failed something failed like failed to delete a reminder maybe yeah we don’t know why maybe the ID was not found of this reminder or something like something different failed otherwise uh we will say reminder deleted successfully so now I think we are completely done with our reminders service as well let’s check out the guide so yeah we’re completely done here so now what’s left for us is to learn uh well probably take a break and check out what’s happening okay react native me I went in art tried node media client but not work PC theme creator um not sure like we would need to kind of check out the exact errors and yeah it’s it would be a bit difficult to do now I’m a first time watching your video you can help me react native snap carousel snap carousels he right now it would be kind of difficult to explain but how to do them but maybe we’ll add them to one of our tutorials in the future and you could check it out but you can check also Chad GBT maybe ask uh how to do it and they will definitely give you a good example i’m Oh yeah the carousel yeah right now it’s going to be kind of tough to show it out i’m really sorry but uh yeah JBD can definitely show and I will try to actually improve it and not improve it but add it to to next tutorial so now we can go to the taskboard and check out the input validation and error handling this is okay looks like it’s a lot but it’s not going to be a lot maybe we’ll do it a little bit uh faster and um so yeah when building APIs input validation and actual correct error handling is very important because it’s it as I say here it ensures data integrity it provides clear user friendly error messages and that’s what we will try to do well first of all we will start with input validation and um it is important because when the user is trying to make a request but let’s say he sends an invalid data that might that might break our application and uh that’s a very bad thing because we want to make it so that our application functions as good as possible and without no breaking without anything so what is our goal is to ensure that the only the valid data that matches our schemas actually enters the system for that we will have implement input validation and we will use as I mentioned zod so you can go to their documentation and check it out but I will briefly like showcase you the most important part well first of all it’s very important to install it so let’s open once again our terminal we can stop the server for now run mpm install zod you you will see in here that it is added now we can rerun the server and um check out what’s next well first of all we will need to create the schemas and define them uh like add data types constraints and to ensure like basically tell our application what is an actually valid schema and what we should expect so for that let’s go to our source and create one more uh folder called uh schemas in here let’s create create a new reminder schema.js and in here let’s define the schemas so first of all you can just copy this one or and u yeah I will actually even go through it here so what we’re saying here is that the reminder schema object should have an ID of number it will have also a reminder which is going to be a string with at least one character and a maximum of 255 characters uh yeah I’m adding these constraints just to showcase you like different examples but you can check out like Z documentation and do them differently we will have also a string of notes which is going to be an optional so if it’s not provided it should this uh this basically z should not throw an error we’ll also have a completed boolean which is also an optional one and if it is not here it should default to false basically because yeah that’s it just created it should be false then it’s very important to have a user ID which is going to be a number and lastly it’s going to have a created ad field which is going to be a string and formatted as a date time so let’s copy this and just paste it inside our schema uh let’s save it but uh for now it’s not yet done because we need to define different this is our main basically object schema that we have in our database for these reminders and here I said uh yeah no so for these reminders so it has an ID reminder notes all of these fields basically but now we need to define a separate schemas for when we’re trying to create and when we’re trying to update so for creating we need to have like basically all of these fields except so what we’re doing here we’re taking this reminder schema the same as here basically referencing this and we’re omitting the values like ID so I we when we’re creating we don’t need to pass the ID we will create it ourselves completed is also you shouldn’t pass it because it’s also going to be always false by default and then created at it’s also don’t pass it because we will create it by ourselves basically the current date time so we’re going go back to our schema and paste this schema uh for create reminder schema now for the for the update it’s once again going to be very different even though like let’s say the reminder itself is here uh required when creating when updating it should be optional so you don’t really need to pass it so also notes you can pass null for notes if you’re trying to let’s say remove your note so it can be nullable and also optional but when you’re creating a note you cannot pass just null so yeah that’s that and lastly the completed is boolean and it’s also optional so if we go here we define it and now we have different schemas for updating and creating so if you go again to zod you can find different um like different uh how to say um functions maybe uh and um yeah read about it there is a lot of different uh validations like it but mainly this is the ones that you will use a lot and you can also ask for chajbt once again use AI when developing to build you uh schema with zod for example just say I will have reminders notes the reminder should be uh required it should have that and that length the you completed will be optional it’s going to be true or false or yes or no and will build you like this and you can use it so don’t forget to use AI okay now that we defined these schemas we need to create the middleware and as I talked already about middleares that will validate these schemas uh basically we will create a validation middleware and to do that we are going to create once again a new folder uh called middle wares and inside it let’s create a new middle and let me check how it should be called in order to have the same okay so yeah it’s going to be called validation middleware and uh let’s keep it nope js so this validation middleware will have uh this piece of code it looks a little bit intimidating let’s first of all just paste it in our validation middleware but I will go through it it’s not that difficult so even here I’m explaining what it does so first of all this middleware will receive uh in here the request response and next um like any express middleware we were always going to pass this request response and next to it this middleware will try to call the schema that we passed and parse it with the request body so basically with the in the schema that we defined are here basically and we will try to compare it in a to put it in a simple ways with the request body which is basically means with the input that user is providing that user is sending us it will try to compare with it and if everything is good it will call the next function which means proceed to the next middleware or route handler uh if it was not correct however we will go into a catch block that means somewhere we had an error and this catch block is not that difficult also to understand first of all we’re checking if the error is a zod error basically from the library that we installed and we as you see we here imported at the top so if the library is a zod error it means the request body did not match the schema that we were expecting so that means that we will try to build this error message in a human readable way so we are looping through the error that we received we are combining this message with different issues so here it might say uh like um reminders is required or something like this and then we’re returning the error with status 400 and saying that the data was invalid but if it was not a zod error that means something else failed i’m not sure what failed and then I will return simply u error status 500 and say that in it was an internal server error so yeah as easy as that now to apply this validation middleware it’s not that difficult either so what we can do remember this function actually let’s maybe close out a little bit of the things because we have a lot of them so the first thing it needs to enter is going to be the routes and we need to say okay so which routes uh are we adding this middleware well first of all let’s import the function that I just called uh validate uh date I think I called it uh validate data so yeah I need this function and I need to import it from it’s going to be from um middlewares/validation middleware so what we will do when we’re calling the create before calling this function we will add a validate data and we are also need to if you remember pass the schema to this validate data function so if you remember as well we created already these schemas so what what we can do here is say import and then we will import the name of the schema so in our we are create reminder schema we need the create schema and we will say imported from and let’s do schemas slash reminder schema and now we will say okay so validate data with this schema and if it’s correct because we are passing we are calling here next from express we will go next into and call this function otherwise if it catches an error here that the schema does not match it will throw an error we need to do the same for the update so let’s do that validate data but if you remember we created a different schema for updating because not all fields are required so we will pass here the update reminder schema but also we need to validate the data before doing anything else so as simple as that we are applying this these validations so here um yeah I’m saying what I suggested and uh what I’m doing and now if I go so let’s um let me think how is it better okay let me show you the let’s say when creating because reminder is uh required if I don’t send a reminder it will say invalid data error and the detail now is saying okay message reminder is required okay That’s very good like if I don’t pass the uh user uh I mean the notes and try to call it with and create it it’s going to work it’s not going to have any notes and completed is false but it’s working if I for example don’t pass the ID and try to create it it’s going to say that the user ID is also required so yeah that’s how it’s working it’s validating if it’s good it will go to the controller if it’s bad it will stop so here for example all of the fields are optional so in theory it will what the thing is checking for is for example if I pass some um actually yeah the thing is checking for because the reminder must have at least one character so for example if I have it like this it will still say that the reminder should be longer but if I pass at least one character and then send the update it will update the reminder to like what I wanted to so this is automatically helping us to like do so many things like catch so many errors and you could in theory even have here for the user ID to check it with the user ID that it would match at least one user ID in the user table you uh I will not show you right now because we’re like a bit short on time but just make sure that check out Chajbet and ask to show an example like that and you will see it and it’s going to be amazing uh it helps us a lot but now let’s see um okay past all this this as well let’s see how can we create custom errors because uh right now we are using throw new error just like you have let’s say in here I know not schemas but in service we’re throwing new error and saying some sort of an error well it has a few issues well first of all and the main one for us is that we cannot send a status uh code in a clean way so for example we cannot say that it was uh internal error for 400 or invalid data I mean 500 or invalid data 400 or it was not found 404 you could do it with this error but it would not be oneliner it would be a long here like at least three lives lines I think and repeating that would be also a nightmare all the time so we will create a custom error class for that and to do that simply inside the source let’s create our last folder called utils and in here we can add error message.js i think call it like this um oh no create custom error sorry my bad uh custom error.js and in here simply pass this code here so what this code does is we are creating a constructor our own class which will extend the error class that we already have here which is defined already but we will change it a little bit well first of all we will call um the parent class which is this one uh with the error message so basically we’re passing the message that bas uh here we provide here so it’s working the same it’s all good we need we can just override it but because we this error class does not have a status code we will call this and we’ll say the status code will be the status code that we provide in when we’re calling our custom error and we’ll see very soon how to provide that status code so before we jump in and right away implement our custom errors everywhere we can also see one weakness so for example here we have a lot of reminder not found reminder not found but what if I say make here mistake remander not found let’s say they’re not like they’re not consistent and later on if I would want to change the name uh for all of them that would be insanely difficult to go through all each of them and define a different error all the time so what a lot of companies are doing they create these constant static error messages and they reuse them that’s a very good practice of doing that it prevents the typos it keeps the code very clean consistent and later on you can even translate everything all of these very easily so it has a lot of pros let’s say to it so to do that actually I was lying not the last folder we will have constants and inside here for the constants we will create error messages so if we go here we say error messages.js JS and simply paste all of these messages that I provided you here we’ll have a few messages one of them is going to be reminder not found or we could have it even more general saying like item not found and here having item not found but let’s leave reminder not found you could have like user not found and more of that then we’ll have invalid data unauthorized forbidden and internal server error these are like one of the more common ones so now if we uh if we just uh use all of that oh yeah first of all yeah let’s uh start using these uh error messages and well first things first very clear one uh we need to adjust the newly created uh schema error where we throw these errors and make them use our constants that we just created so let’s import and let’s uh I already have here like um but okay I’m just going to show you in the code so what we’ll do is importing we are importing error messages from constant constants error messages and now instead of having this invalid data we’ll say error messages dot invalid data and here error messages dot internal server error now these will stay clean and if we any time in the future we want to change let’s say the internal ser error we can just go here and say try again or something like that and it will change to all of these so yeah very clean that’s the first change the second change is we will need to create this middleware to handle these errors because right now if we would have uh let’s say so let me go into one which one get reminder by ID and try to throw this custom error don’t forget to import it from here and let’s say let’s throw uh 404 not found and go to get by ID i think nine should be not found it’s still throwing us internal server error uh and not not found um yeah it’s still throwing us a wrong error well it is happening because we don’t have a middleware that would handle these errors so because if we go to our controller it knows that if something failed I will simply call this message with this message every time no matter what so we need to adjust that and in order to do that we will need to create this middleware so let’s go to our middlewares new file error handler middleware and then inside here we can specify this middleware what it’s doing is basically this error handler receives the error and it checks like okay does the error have a status code uh that we will pass if it has it will apply it if it doesn’t it will throw 500 then it will check okay does the error have a message if we provided it it will uh apply this message otherwise it will default to internal server error message and lastly we will simply as we do here in the controllers uh let me go here we’re sending the status with status code so status status code 500 404 and then we’re returning the error message uh very similarly to this like we have here so let’s copy this let’s go to error handler middleware paste this in and don’t we’re using already the error messages like um the created new ones uh so now that we are we created this middleware if you remember we need to apply this middleware and um but before that that’s actually very good that I checked the guide because even if we apply it we are never we are always calling this like every time um so it’s not good like even though if you are going to throw an error in here it’s always going to uh respond with status 500 and these error messages so what we need to do is go to the controller and if you already remember this next function and instead of calling right away this error we will say call next and we already uh saw this next and it means that call next middleware or yeah or router or whatever so we will basically express will call the next middleware in this case for us but now it’s still not going to work even though we changed it but because we need to uh so yeah now we’re passing the error and I actually forgot to pass the error itself so yeah you need to pass the okay the error to the middleware as well because if you remember let me show you in a second in here where we have this middleware we need to pass here the error and we it is expecting it so that’s what we’re doing here but now we need to apply this middleware so if you go uh well we’ll come back to these if you go to your index you need to add this middleware as the last one because if like as I said like it’s calling the next middleware so it’s going to call this one after the routes we are passing this uh new created middleware so if we go to our index and if we of course we need to import it here as you can see from the guide so let’s do that and we will say simply as the last one app dot use and use the error handler middleware just like we said to use the express.json middleware the same way we’re saying okay now use our custom one that we just created in here okay let’s save it so now that we have this we can go back and actually finally even we can test it with uh our get reminder by ID that we just created that uh where is it uh let me go to where is controller and get reminder by ID h get reminder by ID if no reminder throw custom error reminder not found and custom error where is it define where um did I forgot to export it c No no no it’s utils/custom error uh oh and we’re Yeah so um next is not defined i did not read that correctly so if I go here to our controllers uh we’re not importing this next so basically we’re calling it but we forgot to import it for every also a controller function so the this is what uh express returns like request uh response and also the next function so now that we have it for everything it will now display the error but the error will be this one it’s not standardized yet so if I go here call it it says reminder not found and not capital letters doesn’t look very good so let’s adjust it and make it perfect so error messages dot uh and it’s um reminder not found so if you can see error messages are important from constants so now if we call it it will have reminder not found but it will call it from this so we can say maybe even item not found to just show you that it actually works like this so if I save it and go of course now I need to adjust the name uh in this service because there’s no reminder not found now it’s called item not found so if I send it it says item not found that means it’s using that and it’s perfect so now in this file everywhere where we using the old error we will change it to a custom error and let’s say error messages dot item not found and it’s going to be 404 so here as well like reminder not found we will call the same one these are different so I’m not going to change them just yet and is there any u an any other errors throw error uh so yeah there’s you’re not on you’re not authorized error so let’s adjust this also so it’s going to be forbidden and forbidden I think it’s 400 no 403 is forbidden so okay forbidden you see and I don’t remember them by heart and the last one is something like fail to delete a reminder so we are simply going to check like uh throw uh internal server error which is going to be 500 so let’s save it and now I think there’s no throw new error so now all of the errors are going to be amazing uh so let’s for example let’s try to uh do update 500 uh could not determine data type of parameter 2 um this is a weird one so if it’s 10 uh bind message supplies two parameters but prepared statement it requires so it is some let me check it out that’s actually interesting so if we go to update reminder so we had these new values is not let’s try to console log our query real quick and if we go here if we try to call this what does it uh Okay so we’re saying where ID Oh okay so that’s actually that was my mistake we don’t need to take it from at which position we actually need to take it values.length so the ID is going to be at the last position always so my brain is a bit fried for us it’s already almost 10 so give me some slack but yes here we wanted to say like where the ID is not like equals the actual value of the ID what we were doing before because this one is actually let’s show it as an example that’s a very good thing that we caught it so if we have it like this and then I would leave it only like this and now if I would call this here we are saying okay okay but the ID is the same so maybe I want to do like this 100 so now what we’re saying is that okay so uh set this this reminder where the ID is at position 100 but we’re not even passing that many values here we only have one value and we’re saying at position 100 so this is what that does that’s why we need to keep it only uh values.length because in theory uh we are trying to update uh where the position is and it’s not minus one it shouldn’t be minus one it should be normal one so if we do this one and again console log it so now we’re saying yeah like at position two because we have at position one we have the reminder itself that we’re passing here and at position two because we added it with values push and push adds at the end of the array uh we added the reminder ID so the reminder ID is always going to be the last uh item inside the values array that’s how you a access it by saying values.length length give me basically if the length is two it’s going to be at position two so yeah this is that’s why I said like it it’s weird that we I’m doing this but it was my my bad so now it’s working and we’re saying that item is was not found perfect so if we go to our guide how does Yeah so service handles business and throw structure mhm so here I you can see how everything ties together so basically what we are doing is first of all we are calling the validate data create reminder schema so if we go to our routes here that’s what we are calling if it doesn’t have it it just skips this and right away goes into the controller but if it does have it’s calling the valid data with the schema to validate it and only calls the controller if the schema is correct so that’s what we just checked then controllers call services so if we go to the controller the controller will call the service in here and then this service is going to process the data and do whatever but if the error occurs while processing the let’s say the data like here we we weren’t able to find it will throw this error then what happens is that this error is passed to the error handler middleware via next error so for example if we go back to our controller because an error happened here we’re catching it and we’re passing this error that we threw to the next which is error handler middleware because if we go here the next one is error handler middleware so then uh service uh yeah processes the logic and throw that that error that I just talked to you and then return error handler middleware returns a structured error with a status code and with a message or with a defaulted values so that’s how everything ties in together um so just try to experiment this will make sense if you try to sometimes when you try to do it only once it might be a bit confusing but this is I know how like also started just try to do it once twice and then later you are kind of um tie everything up in your head as well because you forget to add something and then okay you see oh it doesn’t work why it doesn’t work then you say oh I forgot to add maybe this middleware or maybe I forgot to tell the our app to use this middle middleware that I created so it and also if you while watching this have any questions uh feel free to leave it under the video it’s this video will be up and also feel free to ask JBT it will always answer at least give you an idea of the answer but if it’s not clear enough leave us a comment and I’m trying my best to always go back to the videos at least for the first few months and try to reply to you so yes that is actually how we implement and how we properly structure our API our backend and how most of the big companies are structuring it if you come to a job uh interview as a junior or maybe even as an intern knowing all of this will help you a lot and you will even if you don’t have everything like down to a tea how it’s said uh you can already have a good idea of uh okay I remember I saw this I remember it can be here and I remember more or less what models are doing so you can get a gist of where you add your logic where you add your database and how everything ties up it it ties it together basically okay so now that we’re done with our back end it’s time to do the front end the front end is not it’s going to be a very easy one so again I’m not going to spend too much time on it we have a lot of tutorials on this channel uh how to implement it with way bigger examples way more difficult examples this is going to be a very very small uh application i’m seeing that it’s already almost 4 hours so as always uh it’s not going to be a short one but um yeah hopefully it’s going to be a good one so first of all what we need to do for the to create our uh our let’s say mobile application expo application is once again install NodeJS but if you you are 100% have it installed because if you wanted to follow the back end you needed it as well then if you are running it on a physical device you simply need expo go application that you can download on your um device either Android or iOS from the app store and you’ll be able to run the application without any extra setup just like that however if you want to run the application on a simulator on an emulator on your machine you would need some extra setup and here I am providing this setup like you can follow the documentation and um run it uh but for this guide I would suggest you if you are just starting out do not even bother with all of these just check out uh using um Expo Go application it will work just the same and uh if you feel that oh okay I’m liking uh React Native Expo it’s amazing then you can set it up everything here as well again a few things in mind uh Android is available on all operating systems but Xcode which is required for uh iOS simulator is only available for Mac OS however you are still able to publish um iOS applications to the app store uh using EAS but uh again this is not what we’re going to cover it it’s like a next next step uh it’s a lot of theory so maybe we’ll do a tutorial on how to do that but we’ll see so yeah as I said right now let’s use Expo Go i will use a simulator but just because I want to show you the screen of the simulator on on the live stream that I’m doing now so once you’re done with the configuring let’s set up a fresh expo project and it is actually insanely easy just copy this line of code go to your terminal and run this code so what we’re doing here we’re calling create expo app with the latest version we’re saying this is going to be the name of like my folder in my application and we’re saying d- template and it is because um by default here if you don’t provide a template it will create a default template which will already include some tools and which you will probably use for most of the your apps but because I want to show you everything from scratch without having anything else pre-installed we will choose the blank TypeScript So let’s choose that and click enter now while it while it’s installing let’s go back and check out what’s going to happen yes probably you will not see this uh unless you started with the with the Apple like the front end first so if you see this just click yes I trust the authors because you are the author you created everything and now we will need to open another um VS code um project in VS code so to do that what we will do go to your Xcode and you can simply uh either go um file and maybe even new window or I’ve never done it yeah new window works but you can also click commandshiftn uh if you’re on a MacBook or control shiftn if you are on a windows and it will open you with a shortcut this new window so now that you opened it go to files uh and in which I I think I have done a little bit of a mistake because I created this uh Apple reminders clone inside the Apple reminders API folder so if you go here uh we will already see this I will remind us clone so do not do not do that that’s uh we needed to do it in a different folder so yeah I will simply delete it from here if you follow do it like that that’s not an issue and now if you see that you are in your API folder just simply do cd and then double dot that means go one directory back and now I see that I’m in the right uh project directory so now I can actually run this command and create the project that I wanted with a typescript and um yeah now we are going to wait a second it created it so now we can go to our VS code on file open recent uh or no actually open and then we are going to go to uh documents projects and here we should have apple reminders clone let’s open this project and now actually that we’re not going to use the reminders API that much anymore so let’s do it like this okay so now what we need to do is run our front end application to do that click on terminal new terminal and in here simply write mpx and I see that I need to increase it maybe not sure how much um but yeah maybe that’s enough maybe that’s better we can close this clo uh welcome mpx uh expo start once you run this you will see something like this so if you’re using Go if you’re using Expo Go simply scan this QR code and you will right away see the application on your phone just as easy as that no setup nothing for me as I mentioned I will be working with a simulator just to show it uh on the screen so uh I pressed uh Y to open iOS simulator let’s minimize this screen a little bit to fit in the emulator as well so if I go here I know that some of the emulator is hidden behind my camera let me fix that real quick how much something like this probably should be good maybe a bit i can use a bit more and then I can extend this until the end perfect so now that we have our app running we can see uh here open up app tsx and start working on your app so if you go here we can change here the text to anything something like hello world and if we save it we already see the changes that means everything is working everything is set up correctly we can continue working so actually now this is not in the place anymore again okay so yeah here I explain all of that and now let’s create a basic structure once again so just as uh like we did in the API let’s create a new folder in the root directory called source here we will keep all of our source code basically everything that we create inside here the two folders that you will always create especially if you’re using export router is going to be app and also inside we will create components component yes so here we will keep all of our screens uh and we will talk about it soon and here we will keep like Lego pieces small components that we will be attaching in our code so as we can as I said here for screens and navigation app and for components for reusable UI components little Lego pieces now another very important thing is to set up uh path aliases previously I wasn’t that big on them but um because I didn’t want it to overwhelm beginners but they’re actually amazing and without them the project can get a little bit unclear because this is by default how would you import you need so many like go back go back go back and then one directory back one directory back then components and list item if you have path aliases set up you can simply say like this you see how much cleaner it is and to do that the only thing you need to do is actually in the TS config which we have here you can just add this line like we don’t we’re not going to use assets now but so you can only add this but basically only this small part if you add it here uh yeah here you will already set up these path aliases and when I’m let’s say here I’m saying go to at and then component so what it’s saying this at because we’re here specifying uh at and it will be inside the source basically go source components or I could say uh at app or whatever so this is setting up the path aliases and it makes it a lot a lot more cleaner now we can import it just like that perfect we have the setup done now it’s time to implement the expo router and the navigation but before that let me maybe check out the um the chat and Lucas is low-key killing it thank you Catalyn thank you always here always supporting um link lend my error runtime not ready cannot read property style of un undefined probably you didn’t define the style somewhere you’re trying to access it but it’s either not in the right scope so you defined it in the wrong place or it’s like not defined at all uh music forever love you thank you thank you very much uh I appreciate you you’re here actually I remember in Apple News Clone you were here from the start until now you’re here today so I really appreciate the support and I see Reelio is also here still thank you thank you guys very much you’re you’re an amazing support guys always here always supporting huge huge thank you so let me actually take a few sips of water it’s important to stay hydrated oh that was a good sip of water but I like I almost don’t have any left so let me uh Okay um so we’ll be installing now the Expo router for our navigation as mentioned so to do that just go to the official documentation which you can find at um yeah this link or just go to the notion guide that I provided now we can close these because we will no longer need them and we will follow the installation so first of all we need to install all of these dependencies and actual exper itself so let’s do that open the terminal you can do it with terminal new terminal or with a shortcut let’s stop the server with Ctrl C because we will need to rerun it with a clear cache and now we can paste that long code but I see that I included some not necessary symbols like 200 um yeah that’s a long way i could have done it shorter but yeah let’s install all of these libraries they will appear here inside yeah here all of them are installed now what we need to do is we need to change our main entry point in the package.json so let’s copy this and go to the package.json we’re already here and inside here where it says main and right now it’s index j index.ts TS which is here we need to say okay we will change it and now we will uh use the export router entry which is going to be the app folder in a way we’ll see it how it works a bit later then we also need to for deep linking which we will not really explore and but it’s not very difficult we will add our scheme so in the app config which is app.json JSON i like to do it under the slug here add our scheme so let’s say not just uh reminders something like this uh actually like this not just reminders um or even not follow it completely like something like this not just reminders okay now that we added this scheme we could install React Native web and React DOM if we want to have our application also on uh the web right away and it’s just like installing this and that’s it just to save time we’re not going to do it uh but yeah it’s very easy then you will need to also enable the web bundler and then you need to modify the Babel config if you have it already changed by to use basically Babel Babel preset expo but uh by default this is what Expo will use so you will not even have this folder this file in your file structure because this is the default setup for it so the last thing we need to do is we need to run our server again with clear flag that means clear the um clear the cache so now if we run it and open it reload we will see a little bit of an error saying that expo cannot find the routes any like inside the source app directory and we changed that the main entry right now is inside source app so let’s create a entry file called index o not js I am used right now from um tsx yes and now let’s define our let’s say entry file it’s not going to be right now anything too crazy but uh we will have something like export default uh function we will call it home screen because this is going to be our home screen and we will uh return for now simply a view let’s make sure that you import the view from React Native and we will also import text and also make sure that you import it from React Native and in here let’s say hello if we save it we once again hilo hello once we can see it here that means it’s working the expert router recognizes our routes everything is perfect so now that we are no longer using this apps and this index.ts ts we can safely remove these files and nothing will crash nothing will be bad uh because now we our entry file is the index so uh we can also close this and go back to our uh notion guide what we did we installed we created our first screen so now uh let’s see uh should I um let me think like because we will sh okay so I will show you the navigation a bit later on how you can navigate but if you’re following this uh notion guide feel free to just like follow it and um here follow these examples but I don’t want to waste your time at my time right now uh mine is not that important yours is very important important so I’m not I don’t want to waste your time and go through these um little examples that we will later like very soon actually remove and we’ll also still see how the navigation works so you can read and implement but if you don’t want uh let’s just continue so now this is an important one and um the lay let’s a little bit talk about this layouts file this layout file uh is like kind of like a wrapper uh around your screens because by default all of the routes fill the entire screen so this basically is a route and it fills the whole screen but sometimes uh so yeah and if you would move to another screen this will change the full screen everything inside it will change but sometimes you want to um keep some of the things for example the headers so you would want to keep here the header or you would want to keep the bottom tabs as your navigation so in order to keep those things we need this layout that will wrap the screen so it will wrap the screen and it will put uh it will yeah this is going to be the layout and here you would have your screen that you created basically inside it so you would still see everything that you defined inside the layout and also uh what you have inside the screen so in order to think of the um in order to showcase how it works we can create this layout file and let’s create it inside the app and let’s make it layout tsx um so now that we created this layout file in here it’s actually uh let’s export default function and also let’s call it root layout and why we call it root layout it’s because it’s in the root basically the main layout inside the app this is going to wrap everything that you add all of your screens inside here it will wrap this is going to be on top of them so root layout and in here in here let’s return and let’s return a slot from uh actually not a slot stack will be a better example let’s return a stack from I didn’t close sorry didn’t close the tag from react uh expert router and right away after I save you can see this header and this is what stack provides so uh with stack you will have the all the u go back like for example if I would navigate to another screen here it will automatically add go back arrow and it will it will always display the headers we can hide them and I will show you how but this is basically what’s wrapping all the screens in here so actually I kind of have to show you this example but if you add another one let’s say about tsx and uh let’s say about screen and then let’s say here about screen so now if we have the two of these screens and I go here and say link link and then here we say href and I say go to about screen if I click on it you can see that it right away went to this new screen that I just created but because they are both under this layout they both have this header uh because I said this layout wraps around everything that you add inside this app um app directory so now if I and it also added this back so it has also the stack keeps the history of where you went so if I go back I will go to index now there is also a slot but the slot will not return anything basically it will just render the children inside here behind hiding you can see hello from here and if I yeah you like let me add uh here style and some margin top like 50 so here you can see this hello if I click on it we went to about screen but I cannot go back it did not keep this u history so yeah that’s why we will use here the stack for us and we can remove this delete i said I won’t waste your time but I did so yeah this is how you can think about layout and in our let’s say Apple News clone or a Reddit clone that we did recently uh I’m sure Vim also in his clones um use the layout even more like nested layouts because you can have a layout inside a layout this is a bit more complicated so let you can leave it for your next tutorial okay so now uh there’s a quick guide like how uh expert router decides which screen to load basically because you saw here we had two screens but how did it decided to load the index and not about and here um like I can you can read a bit but the basic rule is that expert router will look for the first available index uh file in the project directory and it will once it finds it it loads it right way if it doesn’t find it let’s say at the root level if I had here like something like protect oh not capital protected and I had the index inside here so I can even actually not create here but move it so here inside protected and if I reload you can see that it’s still here like but now the index inside is inside protected and index so it’s looking for the first index that to find and it goes deep deep deep searching for it so here’s a short step-by-step like um explanation of how it finds it uh and here’s a very common also way example of having two subfolders which is going to be protected and O protected will contain all screens that require authentication authentication and they should not be accessed uh any other way and O will hold all of the screens like login register forgot password basically the screens that can be accessed by unauthenticated users so first of all the root layout loads app.layout uh because this is the first thing to be loaded always in every so for example I could even create here another layout and uh in that case uh let me showcase what will happen so if I do this and this will be let’s say protected layout so now it has two headers because the first thing it always does it loads this layout it doesn’t find in the app index it goes into folder in the further it finds here an index but it still loads the layout first so let me move the index out of here because we will no longer need this but let me go through the example so yeah it loads the root layout it it finds there either slot or stack which again acts as a wrapper since there is no index inside the app uh expert router will move into subcategories so expert router will scan those subcategories in order that they appear in the file system so for example this or here if we had like as I said another file something like um I’m not sure like blog blog.tsx it will look them one by one like this so basically alphabetically because this is how they are ordered here in inside so the first valid index found we determine the initial screen since the app has no index it moves deeper in the subcategories uh in the subdirectories and scans them also in the alphabetical order so for example if I had here O and protected it will go into O first and then in protected because it didn’t found any like index in the O it will move next which it will find the index inside protected and immediately load it like even if protected didn’t have an index the expert router would search even deeper and a very common pattern as I say here is to create a tabs folder inside protected and then in this case expo router would continue searching inside tabs and even deeper until it finds the index there so here I’m also specifying what will happen if the off and protected had an index and basically to summarize it it will uh load the o index if you don’t have any layout checks there because you can add any code here to be executed in the layout before even loading here so saying like if uh not o basically if you don’t have o uh then we can uh redirect to somewhere like if you don’t have this in the o uh layout it will load the o index because it found it there first be uh so here yeah here because it’s alphabetically uh so yeah that’s that’s the main gist and we have these these examples in Apple um Apple News clone and Reddit clone and pro Vadim has in other uh projects as well so here if you want you can always go back and check the final code of our root layout uh but we will implement it step by step so let’s go we implemented the expert router let’s check out the tanstack query and why we would use that so TensaQuery is a very powerful tool for state management uh and also like for fetching uh it simplifies it caching fetching synchronizing updating the state so basically instead of handling everything manually it helps us to do it basically with a tanstack query so this is how our request would look like without timestack query we would need to handle the loading we would need to store our reminders when we get them from the fetch request to the state as well we would need to also handle the error separately and set it catch it and finally set the loading to false and here actually it should have been at the start like set it to the loading to oh it’s initially true and then you need to call the fetch reminders and use effect this is a lot of boilerplate for one fetch request so look how much it simplifies everything if we’re using the tanstack query so this is only one advantage of it but also it has global caching so tense query like caches those responses automatically which means that if the same request is made like in multiple components it will be dd duplicated avoiding like unnecessary network calls for every time that you do a request so it keeps that data cached fetched by refreshing in the background and it handles like garbage collection of all data and basically optimizes everything it’s so so good so it’s um to do to use it it’s very easy setup first of all let’s install it with npx expo install so let’s open our terminal we can stop the server once again and I again got this 200 so let’s install tack query and once installed inside the app layout basically the first uh the first file that will be loaded we need to import the query client and define it so if we go to the layout here uh what we will do here is we will import this layout client and let me check if the stream is um yeah okay it’s good so uh we will import the query client and also provider we’ll see later what we do with that we are defining this new query client and then we need to wrap our whole layout with this um query client provider and then pass the client there so it will look something like this so if we keep it here we’re wrapping our whole application because if you remember the layout will be loaded first this is the root layout it’s nothing is going to be above it we are um we’re uh wrapping everything in query client provider and we’re passing this client to it to know like okay basically which client to use now that it’s done uh here you can find the final code but we’ll check out how to do it that’s it you can start using uh sorry you can start using the tanstack query just like that so if we go to our first component how to do that well we already used some components like text and view and they’re react native built-in components and we use them inside here inside our index like view and previously you saw text link is also built-in component from expert router but we can also create our own components so to do that let’s start seeing how everything evolves and basically how everything ties up so first of all let’s start u by displaying the a simple reminder but in order to display that reminder well we kind of need to query it from our uh API that we just created well let’s do just that let’s go to our code inside the index well first of all let’s start the application once we have it ready let’s open it on iOS let’s say reload with by clicking R and then yeah and then let’s start working on it first of all we need to do the query as I said well in order to do that it’s very easy first of all we will define that u or maybe let’s start with use query from tanstack query so we’re basically going to use this fetching and inside here what we need to do is we need to pass a few things well the first thing is the query key and the query key is there to know basically for caching like and you’ll see later on when we add a new um add a new uh record to update the lists and u actually now that I’m thinking I will expand this um after the stream probably tomorrow it’s going to be too late today but uh expand this uh guide and explain a a little bit more inside the tens query um lesson what is the query key and what is the next one that we will use which is query function well query function is kind of um self-explanatory we will run the function um that we will define here basically what this query your query needs to fetch or whatever so in theory what we could do is we could simply uh inside here define like right away uh fetch uh first of all we would say const response and equals now here we need to define like what we are fetching like the URL so we will say await that’s very important we will use the fetch uh function you could use axios or yeah it’s up to you but we will say uh await and it’s going to re a bit complain about the weight but we’ll fix it later and now what we need to do is we need to get our URL the same way as we were doing inside insomnia so for example let’s we’re trying to get all reminders so let’s copy this go back to our code and let’s say okay let’s call uh this basically function and what we need to do is we need to get the response and yeah this response should be parsed to JSON and we can do con um actually we can return it right away so yeah this is what we will do and here you would more time like all the time actually you would have an error catcher so for example here would say if the error is the if the response is not is not okay like the it’s not 200 then something fails so we would say throw uh new error and it depends like now it’s also based on how your team is handling you can define here your own like names fail to fetch a reminder or reminders actually it’s plural or you could reuse the error messages from the like back end that we’re returning so it’s really up to you and um yeah I will show you this way so yeah uh but this like reusing this and maybe you will need even to call this same query somewhere else in your app for example if you have different lists or whatever well there’s a better way once again to handling this and the better way is creating a services folder inside source and inside this services we will provi provide create reminders or maybe reminder service.ts and in here we can like create all of these different functions that will have all of the logic and that we’ll be able to reuse very similar to how we did like we use services in our API so now let’s define actually the first service and the first service function it’s going to be export a sync that’s very important because we this function will be a synchronous we will need to await something to re return so a sync function the name it will be get reminders for now it will have no um no parameters and in here what we will need to do is simply call all of this so we can copy it and paste it uh too much a bit so now we can reuse this get reminders function everywhere in our app just like this and it cleans up the query function here a lot a lot more so what we would do is we would say get uh reminders and make sure it’s important from services here from services reminder service uh get reminders and then we also need to say um okay something here I made a little mistake um oh yeah not little actually a huge mistake but why I removed all of that I don’t know because we only needed to remove this this part and also we don’t need this little part but we need the closing tag and um yeah and this part we also need so here we can move them here and here we will say get uh we will use the oh get reminders from services reminder service let’s fix it a little bit and also we need to call this function so now uh okay it says is yeah so now we will get a little bit of um of an error but it’s not uh because we’re not done with how we are basically defining all of this when uh this get reminders are is called what we need to do is we need to destructure from this use query a few things and we already learned about the structuring so basically what this returns to us so it will return data it will also return is loading so basically data is already what is going to be returned from here so in this case the response JSON the is loading is going to be true while we’re fetching and once we get it will be false so that’s how we control it very easily and then we will also see an error here so now um now we can let’s do it this way yeah what uh why it turned white it says no query client set use query client provider to set one but do we actually have one from tense oh we did not save it after changes so now yeah I I saw a little bubble it was not saved sorry my bad but now that we saved it’s working so now if we go to our uh reminders and if we console log the data here uh let’s go here we can see that we are receiving this data we receiving one completed false created at id notes and reminder by milk we remember that we created this here we are also receiving the reminder uh of one we also remember that we created with it with notes don’t forget to feed him for so we’re we’re already receiving the data from our own API and in order to see that it’s actually from our own API we can go to the controllers reminder controllers and for example for all reminders we can console log saying uh calling this function so if we save it now once once we reload this application sorry once we reload this application if we go to here uh oh we are returning we’re console logging the reminders it’s going to be a little bit messy so let’s do it once again so now if we go here oh what are we console logging still here but we see that yeah calling this function is here uh so that means we are actually going inside here going inside the get all reminders well first of all starting of course from routes getting inside here our model is calling the database with this exact um let’s say query and it returns us back so here was what we’re console logging and it returns us back to controller the reminder says a JSON with status 200 which means everything worked perfectly amazing now that we have this data we still need to handle a few use cases for example if we are loading uh if if we’re still fetching let’s return an activity indicator for users to understand that uh activity indicator from React Native from for users to understand that okay it’s still loading so be patient uh it will be the data will be the list will be here soon let’s add some margin on uh top to see it better like something like 20% uh oh sorry like this let’s save it so now you saw like a short loading period so if I make it like is not loading you see here is g how it’s going to look like you can also pass I forgot like yeah size and you can say it should be large so now the loading is big okay perfect now we also need so for example let’s simulate an error let’s say if response is okay throw an error so now it’s not going to show us anything uh else because what we need to do is we will add yeah here the loading was a bit longer because again a very good thing about uh tens query it’s retrying every time to call again because oftent times um calling the back end again uh is fixing the function you see how many times it called our API and often times this is should be enough like because it it can let’s say at least it can fix the issue by calling it again so we don’t need to set up anything manually it’s right away trying to provide a good response that’s amazing another very cool thing about um about um test query but let’s say if we had an error we need to return this error so in order to return this error let’s define how it should look like so we’ll not do anything too crazy we’ll simply say we render a text and inside here we will uh of course opening this so we’re saying okay don’t we’re not adding just the text but the JavaScript expression and we will say render the error and the message that you return from this error of course we will probably need to add some also styles like here it doesn’t need to be too pretty so now if we load it and actually it’s not going to Yeah let’s wait now here we see failed to fetch reminders so that means that um this this service threw an error and um the utens caught it and returned it to us so now we can display the error message which is failed to fetch the reminders we can also make this a little bit maybe nicer something like bold or not font size font font weight bold and then yeah maybe justify content should we align no align self i think it’s align self center and now it will look a little bit better let’s structure it like this as well yeah I’m spending too much time on this error of course but I cannot leave too bad of a quality okay so now it’s good so we can say if the response was not okay then return me this error otherwise the data should be there so now when the data is there we can start working with it well first of all we already remember this kind of syntax so let’s do that here underneath like if there’s no errors nothing else let’s take uh the data at position zero so basically because if you remember it returns us an array here you can see it returns us an array of objects so we will take the first one inside an array because zero is first and now we can start working and implementing this um slowly this custom component so first of all we will say okay so inside a view we will have a text and the text will say reminder item um I’m seeing some messages um okay uh reminder items and then we will say uh yeah reminder because that’s what we receive we also get the notes so if we save it we can here see buy milk if we say give me at position one it’s going to be one with don’t forget eggs i don’t think if oh we have also at position three so take the dog out for a walk don’t forget to feed him before so this is how we’re already using the data from our database but um imagine if we would need to uh create all of these separately so for example I would need to have another one reminder item two um and saying like something like this this would be a little bit insane first of all and uh not very maintainable second of all and here yeah I’m again saying why we use curly braces because JSX treats everything inside text as a plain default text but in to include dynamic values like here we need to wrap them in a curly brace to tell that it need to be evaluated as a JavaScript expression so to make this a little bit more reusable inside a component let’s create that Lego piece that I was talking about with you let’s call it reminder list item tsx and in here um yeah in here we can uh move all of this logic so that we had here with uh displaying notes and reminders to here so let’s do export default function let’s call it reminder list item and let’s do it return and let’s return something like uh view and also a text we need to import it so you can import it by pressing command Y and make sure that it’s imported command I yeah command I and make sure it’s imported from React Native uh and do the same here and make sure it’s imported from React Native or you can just write it yourself like this so here we also can do the same thing by basically display display some text let’s say here we will be reminder uh and let’s leave it like that for now so now instead of creating this huge code and imagine if there is more styles more text it would be very bad what we can do is we can simply let’s remove the link import this newly created reminder list item from components reminder list item and inside here we can simply use it like that reminder list item so now we’re using this little Lego piece inside our code and u and basically we are able to reuse it and we can use it anywhere in our app like anywhere at all that’s very good but now we’re displaying some random information how do we display the actual information that we need well the same as we were passing props here uh parameters we can pass it to our components so for example we could here say that we want to receive reminder item and now we define what is that reminder item for us it’s going to be let’s say this one and we can even do a second one and yeah do reminder item two uh so now if we save it and now we can see that it displays two but how can we take the data in here and reuse it well it’s kind of not too difficult in here what we will do is we will take the name here reminder item we will destructure it right away to reminder item otherwise you would take it as a props and then you would here do props dot reminder item but we already learned how destruction works we know how cool it is so let why not use that okay we have reminder item now we can start using it so for example if I say reminder item reminder and even reminder item do notes if we save it we are right away seeing the data the actual data that we need which is amazing of course we do see some red warnings saying that it has an any type and TypeScript is not happy about it at all but we will fix it very very soon so now if we go here uh yeah I’m telling that this is how we made it manageable reusable and very scalable i told you how to pass the props and actually yeah like if you would go here and say I can pass hello again hilo hello equals let’s say something like hey we could get this data inside there as well so I would say how I named it so if I go here I called the prop hello so I would go no no no no not full I would here also say hello and now I could simply uh display that instead of what I was displaying before but what I need to do is I also need to pass it here because otherwise it will crash so if I save it here I save it here we’re displaying the hey so we’re displaying the value that we passed which is here this little thing so you can pass as many parameters as you want and it’s going to work you can use them here u the way you need it to be and we’ll see a bit later but for now what we need is the reminder item and display the notes and the reminder itself so yeah we saw how to pass the data uh how to receive the data and how to use it here I’m also like giving you a little bit of an example of uh how it will would you use it if you wouldn’t destructure it here so you could have here props but then do props render item reminder but now that we structure we can do reminder item reminder let’s close the service for now and let’s close uh the let’s let’s make this a bit smaller we don’t need the layout the index will need app don’t need don’t need don’t need so now we can start working on the designs and I have provided you here the final code of the design how everything will look like so if you want just go there copy it and u yeah and you’ll have everything ready but we can do it uh real quick because it’s not that difficult ourselves well first of all we will u have our reminder as untouchable opacity which means it’s going to be pressable so we need to of course pass the on press function to tell what will happen after user presses on it so we’ll say console log and we have pressed amazing that’s very good but we can also pass some styles to it so if we save it now you can see that it’s pressable if I press it’s doing like this little animation but um we need to pass some styles to this whole component because now it looks well to say the least horrible so these styles can be first of all we need to um yeah oh I forgot a bit more i don’t have a design on my on my screen so but if you want actually and I will do that i will uh go here and here I will move it to check the design and it will be a lot easier for me okay so yeah I can see right away that we need to have um little icon beside it and um and then another icon at the end of it so actually without showing to you it’s also not going to be very good good so but here as you can see we have this little button to know if it’s already um completed or not we have a more information button and we have some text here so let’s start doing like from left to the right what we need to add is the the icon so I already have this icon ready and let me copy it so it’s going to be here let’s save it and also uh to use this icon we need to import them from material community icons and we will also need the undesigned later so now okay we have this button perfect that’s very good we also need the uh other button that I talked about which is the um which is the the the information button that’s that’s how you call it probably so let’s do it that way u okay like this let’s save it and we already have some styles to it so we are aligning it at the start like maybe I will remove the styles for now okay so now we have all of them like that well what we we see is that they should be in a row to achieve that that already gives us a very good hint because we want them to be in a row so flex direction row now we have all of that in a row however we don’t want these two to be in a row we want them to be as one component so to achieve that we are simply going to wrap them inside one view and now they will stay under each other but this uh this and this will be a line in a row so that’s already achieves a lot if we would add this for example inside here it’s also going to stay in a column but we want this to be at the end in a row perfect we have this we also want to align all of these items inside like and center them like this for now later we’ll change this but we want them to be centered also we want them to have a gap between each other something like like a small gap between here and here now um now that we have this I’m thinking um what would be the most important part for the Yeah so let’s say we also want this uh information button to be aligned like completely on the right to achieve that we will have margin left and we would have auto amazing that’s that’s what we wanted to do we also it’s a bit too close to the side so we will have margin uh right and we will have like something like five having it a bit uh more outside of the wall okay that’s very good so now the worst thing that like for me here is the text it’s too small it’s um like hard to understand which is reminder what is note so let’s maybe quickly style them it’s not going to be too difficult so let’s do that for the title uh of the reminder we actually don’t need to pass anything maybe if you want to make it bigger maybe we’ll do that for but for the uh notes we definitely see that it is a bit smaller so maybe something like 12 and we see that the color is gray but not and not black so yeah maybe uh I will make it um yeah for now let’s leave it like this may if you want you can do it bigger but now I also want to have a little bit of gap between here and on the bottom so again it’s already saying you what we want to add which is gap and the gap could be of five um but now let’s say that the reminder can be very long uh even longer even longer and now it pushes like our icons out what we need to say is that the flex box that it is in should so basically if everything something that’s inside here is moving out of the flex box that it’s in and you can see the flex box that it’s in by doing background red then move this everything inside like for example if I move remove this you can see that it’s going out and the the flexbox is actually here so I need to do um background blue but you don’t see it because of this but yeah basically what it says is if something is going outside of the flex box please uh don’t do that so we uh can achieve this now what else well uh let’s see the designs well they need to have some sort of uh like more padding around it and like the lines uh under so that means we will be continuing continuing to add styles to the main um main component that wraps everything so first of all I really want to add some margin between them all of them so I will say margin bottom and it should be quite a big margin from example like this and I also want them to be a little bit um separated by a line so to do that we can very easily add a line border bottom width and we can import we can even either say like the width should be 0.5 and then we can say border bottom color and the color will be in our case I see gray or we can from the stylesheet that’s imported from react native very important we can get the hairline line width which makes it a little bit smaller and look better in my opinion so now that we have all of these uh I will I still want to because this line is too close to the to the note let me add some padding uh on the bottom and here we say let something do like five or something like that so now we are kind of moving towards um what we want of course uh here you don’t see the final version it’s too close to the sides but we’ll get to that right now we’re only wanting to solve this and actually here we can move back to reminder item reminder okay so now we have these uh what we want to do next let me check the design so here we kind of are okay yeah here I see that the this icon is not very well aligned so we need to align it with the title here at the top but now it’s in the middle between these two so what I would do here is I would say align uh yourself so align self and align it at the start of the flex box that you are in so it moved it to the top so now it’s kind of um where we want to be not exactly but we will um solve it a little bit later inside the index when we are be applying the styles there okay but now this u button is always pressed how can we control what to dis how it should be displayed well for that I decided that we will use uh state so to use a state what we need to do is first of all dis uh define the variable name a set is comp completed so we need to define the variable name and also say that okay it is going to be a state by calling as a use state from react and it should usually be the first one um a hook so what is a state a state is um do I have an example no I didn’t so basically a state is a variable uh that once it is changed the whole component is rerendered and we’ve talked quite in detailed in Apple News clone about it so if you want check it out maybe only that part but basically what it will do once we change it it will go through everything and adjust it basically or rerender your whole comp whole component to show maybe some changes that we will do right now very soon so again we can define inside the state a default value basically how it is going to be initialized and if you remember our reminder item has a completed field which is basically specifying if the item if the reminder is completed or not but now we still always displaying this completed button well that means we will need to uh render the icon conditionally so if it is completed we will show one thing if it’s not we will show another so here we’ll say if it is completed let’s show what we are actually showing here let’s maybe clean it up a little bit and here like this and here like this okay so now here we Yeah if it is completed we will show this else this little double dot mean else else we will show a little bit of a different icon and I have it here so let me copy paste it um else we will show it incomplete so now it’s a lot closer to what we need to have but now how can we make it completed well actually we will do it by later on calling a mutation but for now what we can do is say set is completed and make it um so the right way would be to take the current state and say make it different so if it is now completed it should not be completed and vice versa so now if I save it I can see that it’s being applied to one of them and it works good but it doesn’t update it in the database this is what we will do a little bit later on but now that we have all of this um I’m feeling that we need to finish styling uh to look to to make it look better so go back to your index and first of all inside the actually go to your layout and inside the stack what we need to do is we need to say okay we kind of don’t need this uh header here so to do that what we can do is um instead of having a stack selflo with a self-closing tag make it like this and inside here we will define stack dots screen we will give a name of this screen basically index that you have here so we’ll say index and we will pass some of the options to it so maybe some styling options which in our case it’s going to be header shown false we could you could also instead of doing header shown false you can have header uh title and say hello you could change not like this you could change here the title but for us what we need to do is just hide it well we can see another issue right away that all the text moved behind like in unsafe area let’s say that way well we can save it pretty quickly saying use safe area view and in this case we will use save area view from React Native uh so if we save it it right away moved out our content outside of this uh notch and inside the safe area so everything that it’s going to render here it’s going to render inside a safe area but let’s give it some styles so first of all if we do background color and do red we can see that it’s only taking up that much space but we need to take we need for it to take up the full space of the screen so we pass flex one basically saying take out the full space of the screen you are in we also need some margins on the side so now that you saw how it works I can remove the background color we also need some uh margins on the side so to do that we can say margin horizontal and it will add margins on here and on here uh if you could do also margin vertical to add it on top and on the bottom but for us we need it only uh horizontal okay now that we have this uh looking a lot better what we need to do as well is to add this uh if we go here reminders uh title and it is very easy i actually even have it prepared so I’m not going to waste your time too much i’m going to paste it and tell you what it does we’re simply uh displaying a text saying reminders we give it a font size of 27 we make it bold we give some letter spacing between each letter we give a color of this and we have a little bit of margin on the bottom of it so now our reminders look a lot uh better okay so what’s next what’s next is going to be um yeah okay I know so the next thing that we need to do even if we are displaying all of these reminders like uh like this the problem is that we still are taking the data one by one how can we make it dynamic so that in the future so if you actually go here and we can go to the next lesson which is type safe component so I was I was thinking to show the list right away but let’s follow the structure so yeah very quickly why do we need TypeScript and why do we use it well it helps us to detect errors errory so helps to tie catch also like type mismatches so for example if a component expects a string but gets a number it will complain about it so for example also if the if it will not have a um uh any type like here and here it will say well uh any type is not good enough to put it in simple words it also ha helps us to catch like these little errors for example if we would say reminder item remain it will complain and say maybe you meant reminder because that’s what reminder item is supposed to have in its type and also it makes it a lot easier to understand the code and understand what component expects and it what it doesn’t expect so I highly suggest everyone use at least start using you don’t need to actually apply the uh types everywhere so for example if you would leave it like this and release it to production nothing will crash everything will work but uh so you don’t need to apply all the types but at least start learning how to do that so inside the source let’s create a new folder called types and inside we can create let’s say reminder uh types.ts and in here let’s paste let’s copy all of this code so here we it’s actually pretty simple what we’re doing we are defining a reminder type and we know that this reminder should ex uh have a number with an uh with ID with an type of number and we can get all of this information from our database so if we go here or like our migration schema that we created or even the zod schema so it expects a ID of number of string it can have a note but note is either string or it can be null if it’s not provided it will have a completed boolean user ID or number and it will have a string of created uh at yes then we will have different types for inserting and for updating so for inserting uh when you’re creating new a reminder is a string which is required but a notes is an optional string that’s why we add this little question mark and even if it’s optional you can have it as a string or as a null value and user ID is also required as a type of number but for updating both of them are optional because you can update only one field so you can update the string um the reminder of a string or notes either a string or if you removed it it it’s going to be a null so now that we defined these types we can save them and um we can update our reminder list item component so here you can just copy but I will show you how to do that step by step because that’s that’s where we are seeing the complaints so at the top here let’s create a new type called I usually what I do just copy this name and add at the end uh props then we can start defining the types so what we know it is expecting to get a reminder it should expect to get a reminder item so let’s copy and paste that and this reminder item should be of type reminder here so it should have all of these fields so if we say reminder it would should suggest us to right away import it from types and we can hear that it imported from types but now it’s still complaining because we did not apply it here so how to apply it uh we simply add double dots here and we say this reminder all of these props okay it should have copied only one all of these props that we receive should match what we defined here so for example if you had here uh hey like we defined earlier you would have here inside also uh hey and it was of type string so because reminder props should receive basically two things but this hey can be also optional so it might be optional it depends on your case but yeah right now we’re only expecting the reminder item and this is how it should be structured so now you see that it’s no longer complaining it’s also a very good uh practice to here to provide names for your states so for example here we know that this is is completed and completed should be of type boolean if you pass a string if you pass a number it will complain so for example if I pass here two uh sorry if yeah if I pass here two it will start complaining because it says it’s not assignable to parameter of type boolean so it has to be either true or false and in our case the reminder item completed it is true or false okay so that’s that it’s very easy we’ll see how you use them even more in the previous tutorials we used them kind of in a especially in the Reddit clone in a more complicated way but this is a very good start to have basically just at least apply types to your components and the data they are receiving that way you will learn and if something you don’t understand like you can copy the error message paste it to any AI tool and it will help you to understand okay what’s the problem here okay so now that we fixed these types the one thing that we can finally get to is the lists because if as I told before adding all of the items like this and let’s say data we could even do like this way but that’s that’s insane that’s way too difficult uh and later on let’s say if people add more reminders in the application you need you would need to if you had this case come back here add new um new values after adding these new values submit your app to uh Apple review or Google play review and only then you can release with new values so this is not going to work we need to make them somehow uh dynamically render and uh basically it doesn’t matter how long the list is it should render them dynamically all the time and for that we can use a flat list from React Native flat list is a very cool list because it’s very optimized it’s rendering only the data that you see in some more screens but it is basically if you are thinking about rendering a list more times than not you are going to use a flat list there are different lists but yes this is what you should think of and it should expect a data and the data should be an array we know that this data that we get from the our query is an array so we can pass it like this but it’s not enough because we need to also define and tell to the flat list okay so how should I render this data so you could say okay so for every component that you render just render hello and because we have three three reminders it will render three hellos still not good enough we need to take the data from those reminders and uh dynamically display them so Every time um flat list goes through the list it goes let’s say inside first object then it goes inside second object then inside third option object and if there’s more continues to do that and every time it goes inside that object object it returns you here basically saying okay here is the object that I’m rendering now tell me how to render it and we will do it by simply saying item and let’s say let’s take reminder because we know that this item item has a reminder field so if we save it we can already see the reminder titles that it’s rendering here but it’s it’s even more powerful than that what you could do is you could say okay so for every item please uh render me reminder list item so the component that we just created of course we can right away see that uh the reminder list item TypeScript is helping us is expecting to get a reminder item so let’s just do that and even if you pass let’s say a reminder item incorrectly it will say that is not assignable to the type reminder that means the type is incorrect the data that you’re passing so you can see how much it’s helping us but if we say item it is because I’m writing this item i’m passing this item to the reminder list and if I go to the reminder list we know how to use all of this data so now if I save this we can see that everything is working very very well so we no longer now need these uh anymore and um we have a decent looking um reminder list of course uh let’s see if we uh align item center yes so we need that but um are they aligned correctly i’m not exactly sure but probably they are yeah you can play around with the styles a bit more but it this is how we want to Oh no yeah I see they are not uh especially this one is not correct because here we have so much white space so in here we can adjust it a little bit and say okay so the title reminder title we know that it always will be here so render it always but we will render the notes only if the reminder item has these notes so if you have them if they are defined if they are not null please render them only in that case so this is also bad because uh it will it might crash your application because you need to uh this should be a boolean basically true or false but notes is a string and uh we need to convert it to a boolean by doing double negation basically so first of all uh yeah doing double negation so if we save it we can see that now it looks good because now it there’s no white space under underneath it if it doesn’t exist and uh yeah it looks amazing so we can maybe increase a little bit the font size as well of the reminder so saying like font size 15 something like this and then maybe this one can be 13 yeah it depends on you you can play around with it but yes now that we have them uh one very important thing that we need to implement is actually uh finishing these and sending it to the data because now if we finish them we reload we can see that they’re not finished anymore so to do that we will use again tens query but we will use this time mutation from it so mutation is the difference between query and mutation mutation is kind of like a post patch uh request the thing that you want to make the changes in to your data and the query is the thing that you only ask for the data it returns and that’s it so what mutation will uh pass down is the mutate which is going to be the function basically that you call when you want to run the mutation so usually you do it on the button press or in this case we will do it on the button press so basically when the user clicks on this we can rename this mutate to our own so let’s say we can call it complete task uh and now you could either leave it like this and it would work if you called mutate but complete task makes a bit more sense it’s easier to read so now we will define like that it should be a use mutation from tenstack query and then this uh mutation should have also expects a few things so first of all it expects mutation function well that’s kind of uh easier to understand we need to somehow like say to it what it needs to do so for now we will uh leave it empty but later on we will add something inside there then it you this is no longer uh required but what we can do is we can call on success and basically when we call on success we are saying that um call this function if the mutation succeeds basically if it runs without any errors so we will do that also because we will need to do that and lastly we will say okay so what should happen if it didn’t succeed if there’s an if there was an error so here we will take the error from it and we will actually right away implement what it will do because we will simply display alert uh from React Native alert and we will say just display an error and also the error message you can adjust this like what happens on error however you want this is a very basic approach but it’s a good one okay so now let uh let’s define another function for mutation well that means we will be doing that inside the reminders service and um yeah uh let’s go and create a new function called so I will copy this one maybe close it and just rename it to complete reminder so here we’ll be completing the reminder but in order to complete reminder we will need uh two things well first of all our API expects ID to get ID and also it expects to get well is it completed or is it uncompleted so we will do that now we can build our query so uh our fetch function so we will say await and now we’ll say fetch inside here once again we could once again uh paste this whole link uh like long query and it would work but what we can do we can also create an environment file in the root here as well so if you create this environment file what we can do with it I will copy paste it and you can say like this is going to be our API URL and it’s actually 3001 and this API URL it’s very important to make it it expo public so that expo knows that it’s ex publicly available um environment variable and that I should be able to access it inside here so now uh I could very easily change my code to instead of calling this whole long let’s say um code what I can do is say okay so simply use process dot environment and then here there was a name I called it expo public and I think it was API URL and then we say slash slash reminders and then if I well now I won’t see that it’s working because I have this error in the renter item list but we can copy this and actually do the same here but of course we will call a different endpoint because we will be calling reminders but now you see okay so these are completely same how do we specify that it this is a post request no longer a get well for that we will open uh more options and here the first thing that we can pass is a method and this method if you remember is a post method because fetch by default is a get method we also need to pass some headers to say that okay the basically the content type will be a JSON type so this is what we need to pass for it and then we will pass in the body itself so basically all of the information but also we need to make sure that this body is in JSON format so that’s why we say JSON stringify and then we will pass um well either the full reminder or um actually only the like the parts that need to be updated so in this case it we only need to update the completed so we called it completed in our back end and then we call is completed like here and it um it will be the I think yeah let’s I think it’s going to be we need to like convert it to a different one so for example if it was completed that means we will uncomplete it uh or if it wasn’t completed we will complete it so if it’s true we’ll convert it to false if it’s false we will convert it to true uh later if we don’t need it I will remove it but yeah actually complete reminder is not a post request it’s a patch request because we’re updating and I forgot about it and we also need to pass the reminders and we also need to pass there the ID of the reminder so now this is getting uh better and the body is only passing the completed and now the rest of the part is exactly the same we were checking if the response is good failed to let’s say update uh a reminder and then if it’s good we will return a response so now we see that this is complaining because of the type so we can say that the ID should be of type number and it’s it’s very easy to add and the uh get completed should be of type boolean so now it’s good if we go back to our reminder list item we need to use this complete reminder function uh from the service reminder from this yeah reminder service so now if you hover on this we see that TypeScript is complaining because it expects an ID and is completed boolean and nothing is provided well first of all we need to the provide the ID and to do that it’s not that difficult because we have the ID here inside reminder item do ID and lastly we need to also um provide whether the reminder is completed or not and for that we will receive it in here so let’s say is reminder completed so you can pass the fun uh variables to mutations in here and then we will pass it back to here but now we see that uh this argument is of type void so we need to type this uh is reminder completed as well and now nothing is complaining everything is good so now what we can do is we can actually pass this once the user press on this touchable opacity we can do uh we can call complete uh not reminder because this is not going to be good we call complete task uh from here like mutation so once we call complete task what we need to do is we need to pass the current state of our task so we are passing this so if the current state is true we’ll pass it as true here but the reminder service is going to transform it and make it false so if we keep it like this um and now uh yeah now if we would change something it would not work so like if I uh and what is the error network request actually that’s very interesting to see so let’s see console.log response and let’s see what the response say to us let’s scroll to the bottom um doesn’t network request failed uh okay i think I wasn’t I didn’t refreshed it and it was showing me this error but now if I try to reload it we can see that after I clicked it it’s completed and if I click again and reload it it’s uncompleted but the problem is that we’re not showing the the like basically the changes in here right away we need to replo reload our app which is very bad so what we will do on success if it succeeded let’s take the data that it returns and set is completed to the data docompleted so basically what we’re doing here is we will set the data set this to completed only if we succeeded and the data is actually completed so now if I save it if I do this we can see that it already updates automatically uh if I yeah and if I reload it’s going to stay like that in theory you could h you could do this with um optimistic UI approach and uh call this even without on success but I just wanted to showcase you how to use this on success uh hook uh not hook like a function that it returns and um yeah this is exactly how you would do that so now we see that we can complete our uh reminders everything is perfect now we need to be able to create these reminders and um that is going to be done let’s see how uh I’m checking if the stream is still here people are still watching okay so now updating the reminder well we can see from our designs that the button to create I mean create new reminder should be uh in the index on the bottom and uh that button is actually I have it I think in my I don’t no I did not add it well never mind we can create it our own so we will have a pressable this is also basically how you wrap a button your custom buttons um and it’s imported from react native so in inside here we can add we need to add an icon that I have prepared as well because as if we see here it’s like a plus but icon i did not do it this way so now I also need to import it uh from React vector icons okay yes and type of React Native vector icons if I save it we see this plus sign right away where we need it and if we didn’t add here the flex it would be here at the top but now if we add this here it moves it where we need it to be and lastly we also need to add the text which is going to say new reminder the text should have be a little bit bigger so let’s pass some styles so the text will be something like font weight so you can also pass numbers here so 600 a little bit more but not too much and we also will pass a color of that little not little but cool orange color and let’s add a hashtag here let’s save it perfect now that’s still a bit um bad maybe we can make it also font size something like 16 and but it’s not uh really aligned how it should be how we would want it to be so we need to pass some styles to the box to the view or the wrap the parent component that wraps it so first of all we again if we want them to be in a row we will pass flex direction row we see that they are not really aligned in the middle so what we will do is we will align them centrally we need to also pass some gap between them so let me make it five and um yeah right now you don’t see it but here it does it will if I scrolled here on the bottom I am 100% sure that it will have no space here so what I want to do is I want to add some margin top and let’s make it 10 perfect so now we have this button um I also if I scroll I see that this reminders always stays on the top but this is shouldn’t happen and it’s very easy to fix inside the flat list we can pass list header component and we can simply pass that title as a list header component so now if I save and scroll it’s going to scroll together this is exactly what we wanted to achieve very good um so now how do we uh navigate to a new screen when we want to update well first of all we need to create a new screen inside our app and we will call it create and also update reminders because this is we can re reuse the same screen for both of the things very very easily and I will showcase you how to do that um so okay we have that um now let’s implement a very export default function uh create update reminder let’s make it return and let’s make it return a view and also a text so now if and import it from react native that’s very important so now if we say here create update save it and now how can we navigate here well if we go to the reminder uh index actually our home screen what we need to do to navigate there is as we already learned we can use link so we need to wrap everything with link from expo router so make sure you import it from expo router we no longer need this view here so we can remove it and now that we have okay now that we have this link here we it expects to have an href it’s like required the only thing that’s required and what we want to pass there is simply this name create update reminder create update reminder if we save it we can already see that something is messed up here and it’s because link only ex expects like to get a string or an icon inside it if you want to have your own some sort of um structure like some sort of a styling what you can do is pass it as child so what this does is basically saying okay I will pass this navigation to the children component but it’s very important that the children component has an on press uh like a parameter and we know that pressable has it so now it’s going to work and if we press here we are navigated to create update reminder screen of course we want to add some changes here and um to do that if we go to our layout we remember that we can style each of them separately so if we go to stack screen let’s close it here we need to pass the name that we’re trying to here implement changes so the name will be exactly this one create update reminder and now in here we can uh once again pass some options but because we will pass more options let’s make it like this so we will say options and inside here open the object and first of all what I really want to do is pass the presentation of model this is not going to be this model is not going to be native to Android because Android doesn’t have this kind of model so it will look a bit differently like a normal screen but it will still work so no worries about that i also because here if I click it’s the title is very random so I want to change the header title and the header title will be something like new reminder by default then I also want to add here like a back button or more like Apple reminders have it says cancel here so I can actually add my own uh header on the left there by simply specifying this and I will pass like a text i have it prepared here so you can just copy it and Okay um give me a what I’m forgetting the header left does not support attribute because it does not have props property uh let me actually type everything on my own because header left and I’m Yeah let’s see i will say text and what if I just say cancel here oh I did not import it from anywhere okay my bad so if I import from here now it will say cancel here but you already saw we can add some styles and I have a color prepared for that so let’s add them now the color is a lot better and we also want to once it’s clicked it should go back so right now it doesn’t do anything so to to go back programmatically we can pass this on press and we can reuse from expo router this little router and here by saying router uh back we can programmatically go back so if I click cancel now I’m going back to the main screen and it’s working like we want it to be perfect we have that ready so now we can start building our create update UI and it’s going to be pretty simple well first of all uh what I want to do oh again so there’s one more thing and maybe I will add it later yes so first of all what I want to do is add text inputs and um because we are severely over time um uh I see the questions uh Ryan I’m watching from Brazil very very nice i hope you will you will enjoy ready i’m when will be the other tutorial tutorial i missed this one we’re doing the tutorials at least trying to do every Friday maybe sometimes it can be every other Friday but we’re trying our best to do it every Friday but no worries because every tutorial you can find on uh this YouTube channel just go to it go to the live tab and you will see all of our tutorials there’s 300 of them uh so you’ll find what you need for sure but yeah so I will simply paste this little part um and I will explain real quick how it works well first of all let’s import the text input from React Native that’s very important and uh let me maybe remove this part it will be a bit easier to explain and now here you see some styles and I’m passing them in a different way and you might be thinking why and um well in the previous ones uh I was maybe even a bit uh lazy no I’m joking but um you can either pass the styles in line the same as we were doing here but if they’re getting longer like for example this one and this can be your homework actually or this one and especially in reminder item here we can definitely do that for this style but we can very nicely extract them in a stylesheet so we could create stylesheet from again it’s very important to import it from react native and we can say stylesheet dotcreate and we will create our own stylesheet so first of all we can add we can see here that we need a divider stylesheet so let’s call it like this and let’s add the styles for divider and I have them prepared here first of all we’re adding bordm bottom width you seen this and we’re saying the border bottom color should be light gray we also want to pass the styles to our input box so uh and we are usually doing that if they they have like a lot of different styles oh my mistake what’s no no uh so yeah we’re usually doing that if there’s a lot of styles like here or if the styles are repeating a lot then it’s a very good practice to extract them like this so here you can see that we set the background as white we gave some margin horizontal on the sides we also gave some margin on the top we also gave the border radius to this white box and of course padding very important because that’s how it would look without it and also we gave a gap between each of the input like this so yeah as your homework do this for um reminders list item and especially at least for this huge style here it’s a good practice to do it this way so now that we have these two inputs we need a way to track of what is being typed there and uh one way of doing that is using a state once again because whenever user is inputting something we need to first of all update it here so and also we need to store that data somewhere so we will do that with use state here so the use state will be a string only and the initial it will be initially it will be an empty string so we need to do the same for the notes as well so we’ll say set notes and it’s also going to be a string and uh initially empty okay that’s very good so now if we want to like how do we attach this text input to the state so that when someone is typing here I can have it inside my state every time and update it so that I could have the latest data when submitting well it’s very easy actually the only thing we need to do is pass to this text input two uh properties one is value so the value is going to be the actual like reminder and here the same value is going to be the notes in this case and also we need a way so when someone is typing to update this value so we will call on um on change text and when the text is being changed we will be calling either set reminders or on change text we will be calling set notes so in yeah in theory you could have it like this and have here text and then like this and pass text like this this would also work uh but um we can simplify it and have it like this and basically it will take that text basically all the parameters that it receives and it will pass it to a reminder so it we can simplify it just like that and the multi-line what it does is basically without it if we have if we typed something let’s say a very long it’s going to do it this way but if we have multi-line it’s going to go down so that’s what we want to do another thing that we want to add is we want to uh add a done button here at the top and uh how can we do that well in here in the layout we couldn’t really do it because after the done is pressed we will need to run the mutation and the mutation we will have it only inside here so how we can do it well first of all let’s wrap uh our our return statement in this like tag it’s uh kind of like a view tag but not really it just allows because return statement can have only one element inside uh so we need to wrap it like this because what we will do next is we will try to add stack dots screen we’re once again uh referencing this screen name so saying name and here now we can pass even more changes so for example if we couldn’t add something in the layout we can add it here very easily so for example here we need to add the header right uh and it should be a button and I already have uh yeah maybe I will do it like it will be a text button it will simply say done and the styles will have only a color so styles will have done like that of course we will have in here on press uh so once it’s pressed we will say we will call a function but for now we will console dot log and say uh pressed something like this okay so now it’s time for us finally to implement our mutation here to save the reminder and to do that it’s going to be quite similar to what we did in reminder list item so first of all uh at the top here we will uh define it so let’s say const we’ll have a mutate and we will rename it to save rem uh save reminder and we will also um continue by initializing it with use mutation from react query and this use mutation will once again have few things first of all mutation function and this will be we will call this service then it will have on success and we will need this and you’ll see why uh so on success we will at this time we will not need to receive the data so we can simply leave it like this but we’ll do some things here and then on error and on error I can simply actually even copy from reminder list because it’s going to be exactly the same uh just import the alert from React Native okay perfect so now we can go to the service uh and add this new service uh basically function which is going to be create uh creating a new reminder perfect so if we go here let’s maybe Okay let’s create from scr no let’s do this i’m already a little bit tired not going to lie and in here we will pass we will uh name it create reminder and what this create reminder expects is only new reminder object and this new reminder object if you remember in the types we already specified how insert reminder should look like so we can simply say insert reminder and don’t forget to import it from the types so now everything is good it’s typed let’s copy this because it’s going to be quite similar to updating the only things that we need to change is we’re no longer needing the ID because we’re calling the reminders but we’re calling the post not the patch and instead of providing like one uh object u one um value we will provide the full object of new reminder and now everything else once again is exactly the same so we’ll check if the response is good if it’s not we will throw an error and here we can also say fail to create a reminder instead so now once we go back here we can start using this create reminder from services very important and in here we need to pass this new reminder so this new reminder is going to be consisting of a few things well first of all it needs to have a reminder itself and a user which is mandatory and it might have notes might not have well so that means there will be some extra logic here so we can do it uh like this first of all we will say okay so we will start building our new reminder um object and this object will have as I said reminder itself so we’re taking it from here and passing as a reminder you could do it like this in theory saying that this is a key this is the value but we can simplify it and this will be key and value and then we will be needing the user ID because we don’t have any authenticated users here and we don’t have authentication yet maybe we’ll do it in the other tutorials but this is going to be the ID that we will pass which is ID one so okay user ID one that’s good and now we know that the notes is not mandatory so if we add here the notes it will always pass it and um basically kind of updated but it’s not it shouldn’t be always passed uh inside the request so what we can do is we can check like if notes is not empty what we will do is we will say that this new reminder object we should add another field called notes and then it’s going to be this notes right now we kind of see the issue and uh it says that notes does not exist on this type so what we need to do here we also need to specify the type here and it will be insert reminder uh and now everything is working because it insert reminder has if you remember um notes as a optional value and it’s either going to be a string and or a null so now after we do all this what we can do is we can return and call the create reminder function with this built reminder object so if we do that let’s try and uh let’s say here hello and for the notes uh we say test so if we click done and uh reload it actually after clicking done maybe um wait a second new reminder and let’s say hello test because now I know it’s um it should also close it but if we click it should we implement right okay so let’s do it like this on success uh let’s first of all already learn how to do that but programmatically close that reminder uh like model so in in expo query we will import the router and inside here we will say routerback so if the if the request succeeds we will call uh router back and go back so let’s see if this is actually a correct uh so we’re doing post with new reminder and if it’s not oh and we’re okay so let’s see let’s try to reload it let’s go to a new reminder and do something like this and uh oh okay so yes you can see that it’s already almost 12 uh in here so uh I am not calling this reminder anywhere so what we need to do in this done on header pressed left we need to call this reminder and yeah basically say this is where uh when it’s going to be executed so let’s go here to the top let’s see the name it’s called save reminder so let’s say save reminder let’s save it and now if we call it uh let’s see if it’s going to work yeah it worked it went back so I can add even another one maybe here you would even uh want to add like a loading state so that you cannot for example add here uh is uh it’s called it’s pending not is loading so let’s say this on press um yeah what we can do let let me think we want to make it disabled but on the button so maybe can we do it like this let’s see uh true and if we say like this and if I yeah it’s not pressable so that’s good so what we say uh what we will say is if it’s pending do not allow to click uh made a screenshot do not allow to click another time so let’s say if we create uh reload we already see those new values but yeah let’s try doing that yeah um is it is this pending i don’t actually remember uh let me console log console log is pending let’s save it it’s false so dis maybe on Okay now it worked but maybe I was pressing on a wrong button but now it’s working so now we can actually also try to test if it actually this works maybe it was no it actually works perfect so we can maybe even make this uh cons uh const is save button disabled so what we will do is we will say that this button should be disabled if uh is pending or uh reminder is not present then it will and it will return uh true then basically it should be disabled but we can simplify this a lot more and then we would need to say else return like false but we can do it very very nicely by simply extracting this and keeping it like this so we say is button saved uh is save button disabled either if it’s loading or reminder is not provided so we will do something like this and we will call it so now if we save it we go here we are no longer and we’re not able to press but here we are able to press and um yeah now we created but let’s see how many only one so that’s good but yeah now the problem is another one like if you add some data here it’s not not appearing here right away and how can we solve this this is a very bad thing so it’s actually quite easy to solve it what we need to do is we need to import the use query client from the tenstack query so here we have uh tack yeah here we will import use query client then inside here below let’s say our routes we will specify as const query client and we will say that we want to use this hook use query client and now we can on success what we can do is we can say query client and invalidate all the queries because now it’s not updating because the cache is basically the same it doesn’t know it needs to be updated but now we say that I’ll update every query that has a key of uh reminders and if you remember we are passing this key in our index so basically here it will update all of the uh queries that has this key so this is exactly what we want so now if I go here and say here updated and here updated almost correctly if I click save we can see right away right away it is appearing here which is exactly what we want to do amazing so now um I’m wondering is actually is pending uh is a news mutation but um I think so i think I think I think so but we can also check 10stack.com 10st query examples and um maybe something like okay so there’s is fetching maybe I can is pending okay not something I was looking for um is this how it is called okay I see a lot uh yeah I was reading the comments but yeah thank you guys very much viva thank you much uh Mayures um Eric Marin Golucas Mexico helpfully thank you thank you very much Jamie yes we are still live and we will be finishing it until the end even though it takes a bit longer thank you very much and yes Lee uh the video will be available in this channel so make sure to check it out after in the live tab and 6 hours in and still nobody understand that Lucas is just an AI robot yes uh Jane with this age of AI you can’t tell who is human and who isn’t yeah indeed indeed but we will be finishing it definitely i’m not sure about the is pending but where is the mutation yeah let’s quickly check out the M yeah here mutations so yes it’s pending perfect but uh mutation is currently running so yeah it is called that way perfect i’m not making it up so now and actually in order to test this completely because I really think I want to keep it high quality uh let’s try to console log it but yeah I can see it’s true if I click um something here it’s going to be true and then yeah perfect very good so now that we have all of these um what we need to do is we need a way to delete them and uh in order to delete them what we need to do is we need to open uh their detail page it’s going to be easy to do let’s just go to our reminders list item and where we have this ant design what we need to do is we need to simply pass on press function so we say on press and then we once again because we’re kind of um navigating there programmatically but um actually why should I do it this way i can do it with a link so yeah this is way better so let’s do it let’s wrap it with a a link and now let’s pass an href and this href will be basically where are we navigating well we know that we will be navigating to create update reminder uh create update reminder so for now let’s leave it like this so of course you see the styles are already kind of a little bit messed up so we will pass it to as child and because design like icons have on press it’s going to work and it’s opening this screen but now what we need to do is we need to populate the these fields with the existing data if we click on here so in order to know on which uh reminder and I already see this vertical line which I really hate so let’s quickly go to index and say here shows vertical indicator and we will say false do not show it so now it’s perfect looks amazing okay so when go let’s go back to reminders list item and how do we know to which uh reminder that we go well to know that we need to pass the ID here and we will pass this ID as a optional parameter because it’s not going to be always present it’s going to be only present if we click and if you go go to create update reminder from here if we click here it’s not going to be present okay okay so that is a little bit uh more interesting so to do that we will add a question mark say that we’re passing the ID and then uh in here we will pass and of course to enable these inputs we need to change it to this quote under the escape button never knew how it’s called probably will never learn but uh yeah so now in here we will pass the ID of the reminder so saying reminder item do ID and you see TypeScript is already suggesting which fields does it have that’s another huge bonus so we say ID so now if we click here we should be receiving the ID of the reminder that we clicked on so in order to get this ID and create update reminder we can extract it from the URL and it’s actually quite easy to do so at the top here we can say const we can uh we need to specify that we’re taking the ID sorry uh so yeah we’re specifying that we’re taking the ID so if we had here name you would have here name as well but we will keep it as an ID because that’s what we are passing right okay perfect this is where we have an ID and now how can we extract it well we can use use uh local search params from uh export router and in here we will take that ID um later on we will have um a little bit of an issue with the TypeScript so I will right away fix it and specify to that the ID that we will receive it’s not going to be an array it’s going to be a string ID of string so now let’s try to console log this ID and see if we’re actually receiving correct IDs so if we save it we can see already that it’s working maybe I do I have this no so if I go let’s say here it says four if I go here it says ID 8 but if I go uh new reminder it’s undefined but it’s still working perfect so now that we have an ID we can query the the reminder based on this ID but this query will be called only if the ID exists so how can we achieve that well first of all maybe um because we will need this ID to pass as a integer and we are receiving in a URL once again the same issue as a string let’s right away pse it like this reminder ID and let’s parse it to integer and let’s pass this ID here perfect so now uh now it’s going to be of type uh integer what’s exactly what we need so here we can call uh we can create our query which is going to be again defined the same as in the index we will be getting data oh no data we will be getting is loading lastly we will be getting error okay that’s good so sorry misclicks so now we’ll say okay so it’s going to be not you state sorry guys it’s almost almost we are almost at the end uh so we’ll be taking it from use query hook and let’s specify what we will do that so first of all we’ll be uh defining a query key and the query key at this point we will call it still reminders because we called it here here reminders and we kind of want to keep it the same because if let’s say here we are uh going to be um invalidating queries it will invalidate all the queries but in order to have all of these uh separately like stored and cached separately what we can do because this is an array we can pass a reminder id here also as a key so now this query will consist of basically reminders and key uh keys key pair of reminders and reminder ID but if I call invalidate queries and I call only with reminders it will still invalidate this query because it will check at the first one so that’s why we call it reminders here as well okay we also need to have uh specify a query function and the function here is going to be um boom and of course we will need to right now define that function but very important thing here is because we don’t want to run this query all the time if the ID is not present we shouldn’t be calling this query so we need to pass on one more property uh called enabled and what we will do is we will say only fetch if id exists so we are doing this um reminder id if reminder ex ID exists only do then uh do the fetching then if it doesn’t exist do not do fetch and we will not need that okay that’s good so now we can go to our reminder service and create once again uh another service to get a reminder by ID so let’s create export and maybe I will copy as well here and get reminder by ID okay so it will of course if we’re getting it by ID it will expect an ID and the ID will be of type number um okay so now we can very easily specify it’s going to look almost exactly like get reminders here uh the only difference is that we will need to pass here also the ID at the end so very easy to adjust it so yeah now that we have this everything else is going to be the same as always uh here we don’t need to really uh yeah we’re checking if the response is okay failed to get a reminder and we will return it so in here now we can call that function and uh I think we called it get reminder by id make sure it’s imported from services and now we need to pass the ID in here because um or actually I think we can right away instead of passing there we can pass it from here because we have it at the top so now once we do this let’s check console um log and let’s check if the data if we’re actually getting the data so let’s try to click at first it’s undefined then it loads the data and then we get it actually so that’s very good but what if we click on new reminder well it’s going to be undefined and this function is not even going to be called so for example we could say here console.log uh called and uh if we go here it’s going to be well called but if we go on here it’s not even going to be called so that’s amazing exactly what we want okay so now that we have this reminder we need to populate the data uh with in these fields with already existing data here and to do that well we can uh introduce a new hook called use effect and this hook will help us to do that uh very nicely but actually before that even before that I would want to handle the loading case because if you saw there was at first some loading the data was undefined and then it was defined so let’s say if it’s uh is loading we will add basically exactly the same styles as here and the error is also going to be the same so you can just copy and paste it here but we need to show uh import the this one first of all yeah and we need to say like handle these state it’s very important um so now you can if you go here you will see a small loading screen which is exactly what we want but now what we will do is we will also call use effect uh query hook not query and once this hook uh when is this hook called well first of all it depends really on the dependencies that you that you have here so for example if I only have a empty array so it’s going to be uh called only when the component mounts so for example here it’s called and I can write anything whatever it’s not being called but if I pass any kind of dependencies here so for example let’s put reminder state as a dependency and now let’s try to call it again when uh I did not save it so yeah let me open it rendered more hooks than in the previous render so Oh okay i need to have this it’s very important never have uh these before uh hooks basically hooks should should always go before because the component every time need to render the same amount of hooks and why it was failing and it’s actually very good that it failed because I have an um I can explain to you because once you once we add it here what it does at first when this component mounts because it’s loading it will return this and it will never go uh down once the loading finishes it will go here and it will render this hook but now because we in the previous render we did not render this hook it will fail and throw us an error saying that we now we’re rendering more hooks than in the previous render so it’s very important to not have these returns uh before any of the hooks that you have here yeah so now if we save it it’s going to work and uh let’s go here so it is called now and now if I type every time this reminder state changes we are calling it again and again and again so this is what how we will reuse um our let’s say use query and how we will set the data that we receive from the API to this already existing states so what we can do here is we can go uh and say okay call this hook on first render and then every time when you uh when the data changes here basically when this changes call it again uh like yeah render it again call it again so what we will do first of all we will check if we have the data so if the data is not empty or undefined then we can call set reminder and set data dot reminder and also we can set set notes and say data do notes perfect uh now if we save it and go here we all right away see the data being populated so now if I press on let’s say the one with notes also we see this right away so this is how we will be able to update it but of course we need to create a one more mutation to be able to update this um um yeah to be able to update it so just under the save let’s create one more last mutation co well actually there will be delete but it’s a very easy one so almost the last mutation called mutate and let’s call it update uh rem reminder perfect so now uh we can also follow the old use mutation structure yeah how is it called let’s add some of these to make it a bit more of the same uh yeah make all of them the same so now inside here once again let’s follow uh how we did before we will call this uh we will have here mutation function which we will need to call and we will have some more changes here and also we will have oh sorry we will have here on su not unsettled on success which we will again we will be calling to invalidate the data and show right away the new changes that we just did and lastly the error is going to stay the same so I’m just going to copy it and paste it so right now actually also success is completely the same because the only thing we need to do when it succeeds is to invalidate the rem all the reminders and then go back so that we could see the changes right away so in this mutation we will have uh a little bit differently so we will also want to build this new reminder basically that we are updating to and in here we will pass the reminder because you can only update reminder notes and completed and also we will have the notes but we will pass the notes only if it exists uh basically if it’s not empty if it’s not uh empty string yes so if it’s an empty string we will pass it null because that’s the structure we kept it uh we kept in our database and that’s what we want to maintain basically if if the user removes um the string and leaves it let’s say goes here removes this and wants to update we need to set it as null and not as an empty string uh so yes that’s that’s what we’re trying to achieve here and also lastly we will just return and we will return the function that we will create in the reminder services now so let’s go here and let’s do like this let’s call it uh okay so update old reminder and in here uh this update function should expect uh the ID that we’re trying to the reminder that we’re trying to update and also the fields so ID I don’t know why I removed it and also it will be updated uh reminder so fields basically so in in here the type will be update reminder type the ones that we here specified okay so now we can call uh this very similarly to actually completing a reminder and we could have actually reused it but let’s make it that way so now that we have all of this code uh the only real difference that we are making here is that we are not passing only the completed but we’re passing the whole no this one the whole updated reminder object so that we could have easily and if you want a challenge you can try to uh implement it basically I just wanted to have a little bit separate concerns and yeah make it maybe a bit cleaner more structured so in here now once we return we can call update all reminder from this service make sure it’s important yes and in here we need to only pass the reminder ID so it’s going to be I think yeah reminder id and also we will be passing the new reminder object that we’ve built here perfect that’s not it we need to understand and basically which function to call or is it going to be called basically uh done or save new yeah save new reminder or update all reminder so to do that what we will do is we will create one function called ondone pressed and what this function will do is it will decide what are we calling so what how we will decide simply if reminder id exists that means we are in a detailed page and we will simply call where is it um we will call this update reminder function yes otherwise if it doesn’t exist uh that means we’re 100% uh saving and creating a new reminder so we will call save reminder function mutation which is here now we need to pass this function to our done instead of calling always save reminder we will call it uh undone pressed so we’ll go here and we’ll check which we need to function to call and it will call appropriately so now if we go let’s say and create a new one let’s say creating um new reminder and let’s say in notes we can add creating new notes if we save it we see that new reminder appeared but if we go here and let’s say rename to update new reminder and update new notes if we save it we can see that it updated this uh reminder itself so that means everything is working as we need it’s very cool very good uh so yeah now we are left with the last last thing and it’s going to be very easy to implement we need a way to remove these reminders because now we are cluttered in here so to do that we will add once we go here to update reminder we will add one more button on the bottom and here again we will decide uh whether to display it or not with saying like if reminder ID exists only then display it and I already have the styles I’m not going to waste too much of of your time here so let’s import pressible uh let’s have this and the the styles will be uh for like as the input box the same as these two the only thing is that for now we don’t have this so let’s say console log and let’s pass for now ss or maybe press okay so now something doesn’t look exactly correct and I don’t really uh why is it exactly like that because of input box but um I wanted to have them Oh okay okay i see because we have them in the same view but it should actually be outside of this view and be as its own separate box to click on delete yes perfect so now let’s simply uh define our last last mutation which is going to be for deletion so okay maybe let’s do it okay let’s do it here so we will create once again we learned it how to do it already so we will call here maybe delete or remove i’m not sure maybe remove reminder and then in here once again equals use mutation hook in here we specify the mutation function which is going to be something that we will create in the services so for now let’s do it this way we will have on success and on success is once again we are we need to invalidate the data because um we need to reflect all of these changes everywhere so we can copy exactly like this and actually error is also exactly the same so we the only thing we need to do is create this uh remove service so if we go to reminder services in here um for the delete we only need actually the um the ID so let’s copy this one uh create it like this let’s rename it say um how delete reminder maybe reminder and now uh that we specify this function let’s implement uh the the um the actual fetch request so let’s say const response equals we again we’re waiting for it where fetch calling fetch and here we’re specifying the link so maybe I will yeah it’s going to look very similar to this so URL so that’s what I’m going to do but if we remember this is actually a delete um request so we need to specify the method of delete so once we do that we can follow exactly the same as here uh structure and uh now we can go to our create update and call delete reminder by passing the reminder ID at here at the top that we have so now let’s test the deletion so now we can see that even if we reload that update new reminder is at the top but if I go here and click okay I forgot to pass it uh as a function so how did I call that mutation remove reminder yes here so if we go here we call remove reminder and let’s save it so now if I click here once we are back we are no longer seeing that anymore so as sad as well if we delete it’s no longer here so it’s working it’s uh yeah perfect uh we are finished with uh finally finished with our full stack application it took us a little bit longer than expected maybe I went too deep uh uh in some of the concepts but I hope it was valuable so yeah hopefully I really did not forget anything but um even if I did we already did quite a lot and also for yourself you can try to implement it even more things so for example one very good um task would be or even let’s say um exercise to do exactly the same but with users because we already created kind of uh the database uh we have the users there so try to do exactly the same and also maybe a list you can also have here but without completing just try to get those users and maybe implement a way to delete those users or if you have more knowledge in the on the like react native front end try to create different lists like um Apple reminders have so for example you could have a completed list and incomplete list this is actually one of the things I wanted to do as well but um yeah we’re severely over time so um yeah you can try doing that yourself so for example if you click go to all uh you will see incomplete or if you click go to completed tasks you will only see these and this is very good for you to continue learning on top of this and um deepening your knowledge and also if you have any questions just uh leave them in the description below oh not in the description in the comment section below i’m always trying to get back and u trying to answer these questions as much as I can find at least a little bit of time maybe sometimes during the weekends uh yeah I really want you to transfer all of my knowledge to you and uh if I can help I will definitely always try it out you can also use cajbt if I am not replying instantly maybe you’ll find your answer there but um yeah I will always be there to try at least and help you but yes hopefully you enjoyed uh this long long um tutorial uh hopefully at least one of you will finish it and yeah that would make me very happy i see some very nice words also and um I’m very thankful for these words uh and um yeah hopefully we’ll meet very soon again and we’ll have uh more of a chitchat zuhari awesome video it was very informative thank you thank you very much for staying for that long i really really appreciate it uh how what great job thank you very much Leonel super understandable thank you very much for this video these comments is actually what’s uh driving us forward and why I’ve stayed for so long and uh yeah even though at the end my wording got a little bit uh let’s say wonky but I tried I tried my best to keep focused keep it informative and yeah Eugene first time being here i hopefully I’ll see you more i usually remember all of the uh people that are at least commenting and we have some of the people here that are coming back at least to say hi for every every tutorial which is insane like wow it’s wow uh yeah guys thank you very much i really appreciate you being here with me and I’ll see

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • React.js Fundamentals: Concepts, Architecture, and Applications

    React.js Fundamentals: Concepts, Architecture, and Applications

    These resources offer a comprehensive introduction to React JS, covering its fundamental concepts like component architecture, JSX, virtual DOM, state management (including Redux), props, and event handling. They also discuss React Router for navigation, the use of hooks, and performance optimization techniques. Furthermore, the material outlines React’s lifecycle methods, conditional rendering, debugging, testing, and provides guidance on becoming a React developer, including prerequisites and common interview questions. The advantages and applications of React, alongside comparisons with Angular and React Native, are also explored.

    React Fundamentals Study Guide

    Quiz

    1. Explain the concept of state in React components. How is it initialized and updated?
    2. What are props in React? How are they different from state, and how are they passed between components?
    3. Describe the purpose of event handlers in React. Provide an example of how an event handler is defined and used.
    4. What is JSX? Why is it used in React, and how does it relate to JavaScript and HTML?
    5. Explain the concept of components in React. What are the two main types of components, and what are their key differences?
    6. What is conditional rendering in React? Describe two common methods for implementing it.
    7. Explain the component lifecycle in React. Briefly describe the purpose of componentDidMount and componentWillUnmount.
    8. What are keys in React lists? Why are they important, and what happens if they are not used correctly?
    9. Define the term “props” in React. What is this.props.children, and what are its possible values?
    10. Describe the purpose of setState in React. Why should you not directly modify the state object?

    Answer Key

    1. State in React components is a way to manage data that can change over time and affects the component’s rendering. It is initialized within the component’s constructor using this.state = { /* initial values */ }. State is updated asynchronously using the this.setState() method, which triggers a re-render of the component.
    2. Props (short for properties) are read-only data passed from a parent component to its child components. They are different from state because state is managed within the component itself and can be changed by the component, while props are external data passed down. Props are passed by including attributes with values on the child component when it is rendered in the parent.
    3. Event handlers in React are functions that are called in response to user interactions or other events, such as clicks, form submissions, or mouse movements. An event handler is typically defined as a method within a component and then passed as a prop to a JSX element. For example: <button onClick={this.handleClick}>Click Me</button>.
    4. JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like structures directly within your JavaScript code. It is used in React to describe the user interface of components in a declarative way, making the code easier to read and understand. JSX is transformed into regular JavaScript function calls by tools like Babel.
    5. Components in React are reusable and independent pieces of UI logic. The two main types are functional components (plain JavaScript functions that return JSX) and class components (ES6 classes that extend React.Component and can have state and lifecycle methods). Functional components are simpler and often used for presentational purposes, while class components are more feature-rich and can manage stateful logic.
    6. Conditional rendering in React is the process of displaying different elements or components based on certain conditions. Two common methods are using if/else statements or ternary operators (condition ? <ComponentA /> : <ComponentB />) within the render method, or using short-circuit evaluation (condition && <ComponentA />).
    7. The component lifecycle in React refers to the series of events that occur from the moment a component is created and mounted onto the DOM to when it is unmounted and removed from the DOM. componentDidMount is a lifecycle method that is invoked immediately after a component is mounted (inserted into the tree). It is often used for tasks like fetching data or setting up subscriptions. componentWillUnmount is invoked immediately before a component is unmounted and destroyed. It is used for cleanup tasks like canceling network requests or removing event listeners.
    8. Keys in React lists are special string attributes that should be included when mapping over an array to create a list of elements. They are important because they help React identify which items in the list have changed, been added, or been removed. Without unique keys, React may not be able to efficiently update the DOM, potentially leading to performance issues and incorrect component state.
    9. Props in React are a mechanism for passing data from a parent component to its child components. this.props.children refers to any elements or components that are passed as children within the opening and closing tags of a component when it is rendered in its parent. Its possible values can be a single React element, an array of React elements, or undefined if no children are passed.
    10. setState in React is a method used in class components to update the component’s state. It accepts an object or a function that returns an object and schedules an update to the component’s state, eventually triggering a re-render. You should not directly modify the state object (e.g., this.state.count = 5) because React may not recognize the change and not re-render the component correctly. setState ensures that the component and its children are re-rendered with the updated state.

    Essay Format Questions

    1. Discuss the benefits of using a component-based architecture like React for building user interfaces. Explain how components promote reusability, maintainability, and scalability in web development.
    2. Compare and contrast state management in functional components using hooks (like useState and useReducer) with state management in class components using this.state and this.setState. When might you choose one approach over the other?
    3. Explain the flow of data in a typical React application that utilizes props and state. Describe how data originates, how it is passed down through the component tree, and how user interactions can lead to data changes.
    4. Discuss the role and importance of lifecycle methods in class components. Choose three lifecycle methods (e.g., componentDidMount, componentDidUpdate, componentWillUnmount) and explain the common use cases for each.
    5. Analyze the different approaches to conditional rendering in React (if/else, ternary operators, short-circuit evaluation, element variables). Provide scenarios where each approach might be most suitable and discuss their advantages and disadvantages.

    Glossary of Key Terms

    • Component: A reusable and independent building block of a React user interface, encapsulating its own logic and rendering.
    • State: A JavaScript object that holds data local to a component and controls its behavior and rendering over time. It is mutable and managed within the component.
    • Props (Properties): Data passed from a parent component to a child component. They are immutable from the child’s perspective.
    • JSX (JavaScript XML): A syntax extension for JavaScript that allows embedding HTML-like structures within JavaScript code, used in React to describe UI.
    • Event Handler: A function that is executed in response to a specific event (e.g., user interaction) occurring on a React element.
    • Conditional Rendering: The process of displaying different UI elements or components based on certain conditions in a React application.
    • Lifecycle Methods: Special methods in class components that are invoked at different stages of a component’s existence (mounting, updating, unmounting).
    • Keys: Special string attributes assigned to elements in a list rendered by React, used to uniquely identify each item for efficient updates.
    • setState(): A method used in class components to update the component’s state and trigger a re-render of the component and its children.
    • Functional Component: A simpler type of React component that is essentially a JavaScript function that accepts props as arguments and returns JSX.
    • Class Component: A more feature-rich type of React component that is an ES6 class, can have state and lifecycle methods, and uses a render() method to return JSX.
    • this.props.children: A special prop that refers to any content (JSX elements, other components) passed between the opening and closing tags of a component.
    • componentDidMount(): A lifecycle method invoked immediately after a component has been mounted to the DOM.
    • componentWillUnmount(): A lifecycle method invoked immediately before a component is unmounted and destroyed.
    • Hook: A special function in React that lets you “hook into” React state and lifecycle features from functional components. Examples include useState and useEffect.

    Briefing Document: React Fundamentals and Mario Game Development

    This document provides a detailed review of the main themes and important ideas presented in the provided sources, which cover fundamental concepts of React.js and a practical example of building a Mario game using React.

    Part 1: React Fundamentals

    This section outlines the core concepts of React.js as explained in the first source.

    Main Themes:

    • Ease of Learning: React is presented as easier to learn compared to other JavaScript frameworks like Angular.
    • “learning react is easier than learning other JavaScript Frameworks”
    • React’s simplicity is attributed to its component-based architecture, simpler file structure, flexible component model, and shorter dependency list.
    • Core Concepts: The source emphasizes several fundamental building blocks of React applications.
    • Components: The UI is built by composing reusable and independent pieces of code called components. Examples given include app.js, counter.js, and index.js.
    • “all the files that you can see inside the source are components of the real so app.js is one component counter. GS is one component index.js is one company”
    • JSX (JavaScript XML): React uses a syntax extension that allows writing HTML-like structures within JavaScript code.
    • “this right here the code that we are able to see is basically jsx syntax so basically this is a JavaScript code but we have written HTML inside the Javascript file so this is called GSX”
    • Props (Properties): Props are used to pass data from parent components to child components. They are read-only from the child’s perspective.
    • “react uses props to pass attributes from parent components to child components”
    • State: State allows creating dynamic and interactive components. It is private to a component and can be updated to trigger re-renders.
    • “UST state zero initializes account State variable with the initial value of zero and after that count holds the current count and set count is a function that updates the value so state in react is persistent across renders meaning count will retain the value until it’s updated by set count”
    • Event Handlers: These are functions that respond to user interactions (e.g., clicks) and can update the component’s state. Examples include increment, decrement, and reset functions.
    • “these functions are used to update the count State based on the user actions first of all we have the increment so it increases the count by five each time it is called”
    • Styling: CSS is used to style React components. The example mentions style.css and various CSS properties and techniques like font family, display, justify content, alignment, height, background color, hover effects, animations, keyframes, and media queries.
    • Component Lifecycle: React components have a lifecycle with different phases (initial, update, unmount), and lifecycle methods are called at specific points.
    • Conditional Rendering: React allows rendering different components or parts of the UI based on certain conditions. Methods include if/else statements, element variables, ternary operators, and short-circuit operators.
    • “conditional rendering is nothing but if a given statement is true then the if statement executes or else the L statement will execute”
    • Preventing Rendering: Components can prevent rendering by returning null from their render method.
    • “to do this return null instead of its render output”
    • Refs (References): Refs provide a way to access DOM elements or component instances directly.
    • Keys: Keys are used to uniquely identify elements in lists, helping React optimize rendering.
    • React Router: A library for adding navigation and routing to React applications, keeping the UI in sync with the URL. Different types include BrowserRouter and HashRouter.
    • Context API: A way to share state between components without explicitly passing props through every level of the component tree. Hooks like useContext are used to consume context values.
    • useReducer Hook: An alternative to useState for more complex state management within functional components, similar to Redux in concept.
    • useEffect Hook: Used for performing side effects in functional components (e.g., data fetching, subscriptions). It includes a cleanup function.
    • useLayoutEffect Hook: Similar to useEffect but runs synchronously after all DOM mutations. Should be used cautiously to avoid performance issues.
    • Redux: A pattern and library for managing and updating application state in a predictable way, especially for complex applications with global state. Key components include Store, Actions, Reducers, and Dispatcher. Unidirectional data flow is a core principle.
    • Testing: React applications can be tested using frameworks like Jest and Enzyme. Different types of testing include component testing (snapshot testing), integration testing, and end-to-end testing.
    • Version Control with Git: Git is used to track changes in code and collaborate with other developers. Common Git commands like init, add, commit, push, pull, branch, and checkout are mentioned.

    Important Ideas and Facts:

    • React is a library focused on the view layer of an application.
    • Components are the fundamental building blocks of React UIs.
    • JSX makes it easier to write and understand UI structures within JavaScript.
    • Props are immutable from the child component’s perspective.
    • State changes trigger re-renders of the component and its children.
    • Lifecycle methods allow performing actions at specific stages of a component’s existence.
    • Conditional rendering enables dynamic UIs based on application logic.
    • Refs provide a way to interact directly with the DOM or component instances when necessary.
    • Keys are crucial for efficient rendering of dynamic lists.
    • React Router enables building single-page applications with navigation.
    • Context API offers a way to avoid prop drilling for shared state.
    • useReducer is suitable for managing complex state logic.
    • useEffect is the primary hook for handling side effects.
    • useLayoutEffect should be used for DOM measurements or synchronous layout adjustments.
    • Redux provides a centralized store for managing global application state.
    • Testing is essential for ensuring the reliability of React applications.
    • Git is a widely used version control system for collaborative development.

    Quotes:

    • (Regarding state persistence): “state in react is persistent across renders meaning count will retain the value until it’s updated by set count”
    • (Regarding the purpose of event handlers): “these functions are used to update the count State based on the user actions”
    • (Defining components): “all the files that you can see inside the source are components of the real so app.js is one component counter. GS is one component index.js is one company”
    • (Defining JSX): “this right here the code that we are able to see is basically jsx syntax so basically this is a JavaScript code but we have written HTML inside the Javascript file so this is called GSX”
    • (Purpose of props): “react uses props to pass attributes from parent components to child components”
    • (Purpose of conditional rendering): “conditional rendering is nothing but if a given statement is true then the if statement executes or else the L statement will execute”
    • (Preventing rendering): “to do this return null instead of its render output”
    • (Flux as data flow management): “flux is a pattern for managing the data flow in your application”
    • (Unidirectional data flow in React): “data flows only in One Direction”
    • (Keys for unique identification): “keys are the elements which helps react to identify the components uniquely”
    • (Redux for global state): “Redux helps you manage Global state that is actually the state that is needed across many parts of your application”
    • (Jest as a testing framework): “zest is a fast testing framework it act as a test Runner assert library and moing library”
    • (Enzyme for React testing): “enzyme is a JavaScript test utility for react that make it easier to assert manipulate and derse your react component output”
    • (Git for version control): “Version Control is one that record changes for document computer program large website and other collection of information over time it allow multiple user to manage multiple revision of same unit of information”

    Part 2: Mario Game Development with React

    This section details the structure and implementation of a Mario game built using React, as described in the second source.

    Main Themes:

    • Component-Based Architecture in Practice: The game is built using a modular approach with numerous components organized into atoms and molecules directories within the components folder.
    • atoms: Basic building blocks like Birds, Bricks, Clouds, KeyMessage, Obstacle, and Sun.
    • molecules: Compositions of atoms or other molecules, representing more complex UI elements like Footer, LoadingScreen, Mario, Corrector (likely character controller), MobileControls, Title, and Score.
    • Asset Management: The game utilizes an asset directory to store audio files, fonts, and images (including GIFs for animation).
    • “in this there is a section named esset in this we have included the audio font and the images that we are going to use”
    • State Management (Likely with Redux): The Obstacle component explicitly imports and uses Redux hooks (useDispatch, useSelector), suggesting that Redux is used for managing the game state (e.g., game running status, speed, object positions).
    • “It also Imports Redux Hook from the state management so after that dis patch is used to send actions to the Redux store is playay and speed are selected from the Redux state”
    • Animation Techniques: Components like Birds, Bricks, and Clouds use CSS animations (defined with @keyframes and potentially triggered by state changes using class names like bird animate, brick animate). The Obstacle component dynamically adjusts animation duration based on game speed.
    • “if is ready is true it adds the class bird animate which likely triggers an animation”
    • “The style props adjust the animation duration based on the speed making the animation faster or slower depending upon the game’s current speed”
    • Event Handling for User Interaction: The KeyMessage component indicates that the “Enter key” starts the game and the “space key” is used for jumping, implying the use of event listeners to capture keyboard input and trigger game actions (likely managed within the Mario or a game controller component).
    • “inside this we have basically created one press container and we have given two paragraphs including Enter key and space key so here Enter key is for starting the game and space key is for jump”
    • Audio Integration: The Mario component imports and likely uses audio files for jump, death sounds, and background music, managed using the useMemo hook for optimization.
    • “audio files for jump death sound and various hooks from the react and reds so after that this used dispatch hook allows dispatching actions to the redex store several State values are selected from the redex store to manage the game State such as whether Mario is dead the game is loading or the Mario’s position and the Dimensions”
    • “for this we are using use memo hook to create audio objects for jump die and background music this ensure that these objects are only created once optimizing the performance”
    • Collision Detection: The Mario component retrieves the position and dimensions of obstacles from the Redux store to implement collision detection logic.
    • “these selectors retrieve the position and dimension of two obstacles allowing for the Collision detection”
    • Scorekeeping: The Score component manages the current score, last score, and high score, potentially using localStorage for persistence. It uses useEffect with a timer to increment the score while the game is playing.
    • “the score shows the current score from the RCT store and the last score shows the last score recorded and the play is basically a Boolean indicating if the game is currently being played die is basically a Boolean indicating if the game is over and dispatch is a function that is used to dispatch the action of the Redux store”
    • “this basically initializes the state variable high score it retrieves the high score from local storage passing it as an integer or defaults to zero if the high score is not found”
    • “this use effect runs whenever the dependencies change that means incrementing the score if the game is being played or not over it sets the time out to increment the score by one to every milliseconds and then updating the last score and the high score”
    • Loading Screen: A LoadingScreen component suggests that the game handles loading states, potentially waiting for assets to load before starting.
    • Mobile Controls: The inclusion of a MobileControls component indicates support for touch-based input on mobile devices.

    Important Ideas and Facts:

    • The game demonstrates a real-world application of React’s component-based architecture for organizing a complex UI and game logic.
    • The separation of components into atoms and molecules promotes reusability and maintainability.
    • The use of Redux for state management suggests a need to manage global game state across multiple components.
    • CSS animations and dynamic styling based on game state create visual effects and responsiveness.
    • Event listeners are crucial for making the game interactive.
    • Audio feedback enhances the user experience.
    • Collision detection is a fundamental aspect of gameplay.
    • Scorekeeping provides a way to track player progress.
    • Handling loading states ensures a smoother user experience.
    • Mobile controls extend the game’s reach to different platforms.
    • The index.js files within the components, atoms, and molecules directories serve as central export points for the components within those folders.

    Quotes:

    • (Component organization): “inside this components we have one section that is atoms in this we have included all the components that are being used in this game for example we are using Birds bricks clouds key message obstacle sun and all so after this we have this molecules in this we have included the footer the loading screen Mario the corrector and the mobile controls again we have included the title and the score”
    • (Asset inclusion): “in this there is a section named esset in this we have included the audio font and the images that we are going to use”
    • (Redux usage in Obstacle): “It also Imports Redux Hook from the state management so after that dis patch is used to send actions to the Redux store is playay and speed are selected from the Redux state”
    • (Animation in Birds): “if is ready is true it adds the class bird animate which likely triggers an animation”
    • (Key bindings in KeyMessage): “Enter key is for starting the game and space key is for jump”
    • (Audio in Mario): “audio objects for jump die and background music this ensure that these objects are only created once optimizing the performance”
    • (Score and localStorage): “it retrieves the high score from local storage passing it as an integer or defaults to zero if the high score is not found”
    • (Component export in components/index.js): “each Line Imports the component of specific file path for example bird component is imported from the birds file the imported components are presumbly react components that will be used in the application to render the different parts of the UI and after that this line exports all the imported components into single object by doing this it allows other modules to import any of these components easily from one Central File instead of importing each of them individually from their respective files”

    This detailed briefing document summarizes the key concepts and practical application of React.js as presented in the provided sources. It highlights the fundamental principles of React development and showcases how these principles are applied in the creation of an interactive game.

    React Core Concepts and Mario Game Structure

    1. What are the core concepts of React demonstrated in the counter app example?

    The counter app demonstrates three core concepts of React:

    • State: State is data that can change over time and affects the component’s behavior and rendering. In the counter app, the count variable, initialized to zero, represents the component’s state. The setCount function is used to update this state. React state is persistent across renders, meaning the count value is retained until explicitly updated.
    • Properties (Props): Although not explicitly manipulated within the counter app itself, the explanation mentions that components can receive data from parent components through props. Props are read-only and are used to pass data down the component tree.
    • Event Listeners: Event listeners are functions that respond to user interactions or other events. The counter app defines event handlers like increment, decrement, and reset. These functions use setCount to update the component’s state in response to button clicks, making the component interactive.

    2. What is JSX and why is it a core concept in React?

    JSX (JavaScript XML) is a syntax extension for JavaScript that allows developers to write HTML-like structures directly within their JavaScript code. In React, JSX is used to describe the user interface of components. It is a core concept because:

    • Declarative UI: JSX makes it easier to visualize and describe the desired UI structure, as it closely resembles HTML.
    • Component Composition: JSX is used within the render method of React components to define what they should output. This facilitates the composition of complex UIs from smaller, reusable components.
    • Embedding JavaScript: JSX allows embedding JavaScript expressions within the HTML-like syntax using curly braces {}. This enables dynamic rendering based on component state and props.
    • Compilation: JSX code is not directly understood by browsers. It is transformed into standard JavaScript code (specifically, calls to React.createElement) by a build tool like Babel.

    3. How does React handle styling of components?

    React can handle styling through CSS. The example project includes a style.css file where styles are defined for various HTML elements and React components. These styles are then applied by importing the CSS file into the corresponding JavaScript component files. The example demonstrates styling for the body, app, counter, and button elements, including hover effects. React also supports inline styles (applied directly to elements using a JavaScript object) and CSS-in-JS libraries, although these are not shown in this basic example. Media queries can also be used within the CSS files to create responsive designs.

    4. What is the role of components in React, according to the sources?

    According to the sources, components are the fundamental building blocks of React applications.

    • Modularity: React applications are structured as a collection of independent and reusable components. Each file within the src directory (like app.js and counter.js) represents a component.
    • Reusability: Components can be used multiple times throughout the application, promoting code reuse and maintainability.
    • UI Decomposition: Components allow developers to break down complex user interfaces into smaller, manageable pieces. This makes it easier to develop, test, and understand the application’s structure.
    • Data Management: Components manage their own state (data that can change) and receive data from parent components via props. They define how data is rendered and how user interactions are handled.

    5. Can you describe the structure of the Mario game project in terms of components and assets?

    The Mario game project is structured into two main sections within the src directory:

    • assets: This section contains the static resources used by the game, including:
    • audio: Sound files for game events.
    • font: Custom fonts for text elements.
    • images: Sprite sheets and individual images for characters, backgrounds, and other game elements.
    • components: This section is further divided into:
    • atoms: These are the smallest, indivisible UI elements used in the game. Examples include:
    • Birds: Renders and animates birds in the background.
    • Bricks: Renders and potentially animates brick elements.
    • Clouds: Renders and animates clouds in the sky.
    • KeyMessage: Displays instructions for game controls (Enter to start, Space to jump).
    • Obstacle: Renders and manages the movement and collision detection of game obstacles.
    • Sun: Renders the sun in the game’s background.
    • molecules: These are compositions of one or more atoms, forming more complex UI elements or game entities. Examples include:
    • Footer: Displays copyright information.
    • LoadingScreen: Shows a loading animation.
    • Mario: Represents and handles the logic and rendering of the Mario character, including movement, jumping, and collision detection.
    • TheCorrector: Likely related to game logic or interactions.
    • MobileControls: Provides on-screen buttons for mobile users to control Mario.
    • Title: Displays the game’s title and logo.
    • Score: Manages and displays the player’s score and high score.

    The project also has index.js files within both atoms and molecules directories, which serve to import and then export all the components within those respective folders, providing a convenient way to import them elsewhere in the application.

    6. How does the Mario game handle animation and movement of game elements like birds and obstacles?

    The Mario game handles animation and movement using a combination of CSS animations and JavaScript logic within the React components:

    • CSS Animations: Components like Birds, Bricks, and Clouds utilize CSS animations defined in their respective .css files. The JavaScript components (Birds.js, Bricks.js, Clouds.js) use React’s useState and useEffect hooks to conditionally apply CSS classes (e.g., bird animate, brick animate, cloud animate) to the elements. These classes trigger the animations defined using @keyframes in the CSS. The useEffect hook often listens for the document’s load event to ensure animations start after the page is fully loaded.
    • JavaScript-based Movement and Updates: The Obstacle component uses JavaScript and React’s useEffect hook, along with Redux for state management, to handle the movement and positioning of obstacles. An interval (set to every 100 milliseconds) is used to periodically:
    • Access the current dimensions and positions of the obstacle elements in the DOM using useRef and getBoundingClientRect().
    • Dispatch actions to the Redux store to update the obstacles’ state (height, left, top, width).
    • The animation speed of the obstacles is controlled by the speed value from the Redux store. The Obstacle.css file likely defines CSS animations (obstacle1-move, obstacle2-move), and the animation-duration style is dynamically adjusted based on the speed prop.
    • Mario’s Movement and Collision: The Mario component also uses state, event listeners (for keyboard input), and likely Redux to manage its movement (jumping) and collision detection with obstacles. Key presses trigger state updates, which in turn affect Mario’s position and animations (potentially through CSS classes or inline styles). Collision detection is performed by comparing the positions and dimensions of Mario and the obstacles (retrieved from the Redux store).

    7. What role does Redux play in the Mario game project, based on the excerpt?

    Based on the excerpt, Redux plays a significant role in managing the global state of the Mario game:

    • Centralized State Management: Redux provides a centralized store to hold the application’s state, making it accessible to different components without the need for prop drilling through multiple levels.
    • Game State: The Obstacle and Mario components both interact with the Redux store. The Obstacle component selects isPlay (indicating if the game is running) and speed from the store and dispatches actions to update the obstacles’ dimensions and positions. The Mario component also uses Redux hooks like useDispatch and useSelector to manage its state, such as whether Mario is dead (isDead), the game’s loading status (isLoading), and Mario’s position and dimensions.
    • Collision Detection: The Mario component uses selectors to retrieve the position and dimensions of the obstacles from the Redux store, enabling collision detection logic.
    • Score Management: The Score component also interacts with the Redux store. It selects the current score, lastScore, play status, and die status. It also dispatches actions to update the Redux store with the score and potentially the high score.

    In summary, Redux in this project facilitates communication and data sharing between various game components (like Obstacle, Mario, and Score) by providing a single source of truth for the game’s state.

    8. What are some advantages of using React, as highlighted in the introductory and concluding sections of “01.pdf”?

    The introductory and concluding sections of “01.pdf” highlight several advantages of using React:

    • Easy to Learn: React is presented as being easier to learn compared to other JavaScript frameworks like Angular. Its core concepts are relatively straightforward, focusing on components, JSX, props, state, and event listeners.
    • Efficient, Declarative, and Flexible: React is described as efficient, allowing for optimized updates to the DOM. Its declarative nature means developers describe the desired UI state, and React handles the rendering. It also offers flexibility in how developers structure their applications.
    • Component-Based Architecture: React’s component-based approach promotes modularity and reusability of code, making it easier to build and maintain complex UIs.
    • Simpler File Structure and Component Model: React generally has a simpler file tree and a flexible component model, reducing the cognitive load on developers.
    • Shorter Dependency List: Compared to some other frameworks, React tends to have fewer dependencies, simplifying project setup and management.
    • Large and Active Community: While not explicitly stated in these excerpts, the popularity of React implies a large and active community, providing ample resources, support, and third-party libraries.
    • Suitable for Businesses: Due to its simplicity and efficiency, businesses are increasingly inclined to use React for their web application development.
    • Performance: React’s efficient rendering mechanisms (like the virtual DOM, though not detailed here) contribute to better application performance.

    React JS: A Comprehensive Overview

    React JS is a popular open-source JavaScript library developed by Facebook for building dynamic and interactive user interfaces. It is widely used for creating single-page applications where seamless performance and efficient UI updates are crucial. Known for its component-based architecture, React JS allows developers to build reusable UI elements, making development faster and more organized. It is considered an essential tool in today’s web ecosystem due to its flexibility and efficiency, powering many dynamic and interactive web applications.

    Key aspects and features of React JS discussed in the sources include:

    • Component-Based Architecture: UI is broken down into reusable, self-contained components, each with its own structure and behavior, allowing for independent functionality. Applications built with React are essentially trees of components.
    • Virtual DOM: React uses a lightweight copy of the actual DOM. Instead of directly updating the real DOM, React updates the virtual DOM first, calculates the changes, and then updates only the necessary parts of the real DOM. This significantly improves performance by reducing the overhead of direct DOM manipulation. The virtual DOM works in three steps: rendering the entire UI in the virtual DOM, calculating the difference compared to the previous state, and then updating only the changed elements in the real DOM.
    • JSX (JavaScript XML): It is an XML or HTML-like syntax used by React that extends ECMAScript, allowing HTML-like text to coexist with JavaScript code. JSX is transformed into standard JavaScript objects by pre-processors like Babel. It makes HTML codes easier to understand and can boost JavaScript’s performance. Browsers cannot read JSX directly and require transformation into JavaScript.
    • One-way Data Binding (Unidirectional Data Flow): Unlike some frameworks with two-way data binding, React follows a single direction of data flow from parent to child components. This makes the code more stable, easier to debug, and predictable, ultimately improving application performance. Flux is an architectural pattern used by Facebook with React that enforces this unidirectional data flow, involving a dispatcher, store, actions, and views. Redux is a popular library for state management in React applications that also follows these principles with a single store, actions, and reducers.
    • Server-Side Rendering (SSR): React allows for pre-rendering the initial state of components on the server. The server sends a fully rendered HTML page to the browser, leading to faster initial page load times and improved SEO.
    • Component Lifecycle: React components have lifecycle methods that allow developers to control component behavior during different phases, such as mounting (initial rendering), updating (due to state or prop changes), and unmounting (removal from the DOM). Examples include componentDidMount and componentWillUnmount.
    • React Hooks: Introduced in React 16.8, hooks are functions that allow developers to use state and other React features in functional components. They make it easier to share stateful logic between components and work with functional components without needing classes. Commonly used hooks include useState, useEffect, and useContext. Custom hooks can also be created for reusable logic.
    • Props (Properties): These are read-only components that are passed down from parent to child components to supply data. Props must be kept pure (immutable), maintaining the unidirectional data flow.
    • State: State is the heart of React components, representing the source of data that determines how a component renders and behaves. Unlike props, state is mutable and can create dynamic and interactive components. State is managed within the component itself using this.state and updated using this.setState(). Direct modification of state is discouraged.
    • Keys: Keys provide a unique identity to components, especially when rendering lists of elements. They help React efficiently update and reorder elements in the DOM.
    • Reusability: React promotes the creation of reusable UI components, which speeds up development and makes applications easier to maintain. The “write once, use it anywhere” principle applies to React components.

    Reasons to Learn React JS highlighted in the sources:

    • Component-based architecture for building dynamic and efficient applications.
    • Virtual DOM for faster UI updates and improved performance.
    • Increased job opportunities: There is a high demand for React JS developers globally, with a significant increase in job openings.
    • Attractive pay scale: React developers generally command competitive salaries.
    • Easy migration: React facilitates migration from other technologies and older versions of React with features like deprecation warnings and codemod scripts.
    • Reusability of code: Components can be reused across the application, reducing development time and effort.
    • One-way data binding: Makes code more stable and easier to debug.
    • Flexibility: React can be integrated with other libraries and frameworks and is suitable for large and complex web development projects.
    • Strong Community Support: Being an open-source library, React has a large and active community, providing extensive documentation, resources, and support through platforms like GitHub and Stack Overflow.
    • Testability: React views can be treated as functions of the state, making applications easier to test and debug.

    Prerequisites for learning React JS:

    • HTML: Standard markup language for creating web pages.
    • CSS: Technology for styling web pages.
    • JavaScript: Lightweight, interpreted programming language for adding interactivity to web pages. Familiarity with ES6 (ECMAScript 2015) standards, including its syntax and features, is also important.
    • npm (Node Package Manager): Default package manager for Node.js, used for managing JavaScript packages and modules.
    • Code Editors/IDEs: Platforms like Sublime Text, Atom, and Visual Studio Code for writing React code.
    • Basic understanding of the DOM (Document Object Model).

    React Architecture:

    React is often described as the “V” (View) in the MVC (Model-View-Controller) architecture, although it’s more aligned with a component-based approach. For the “M” (Model) architecture, patterns like Flux and Redux are commonly used to enforce unidirectional data flow and manage application state. A React application is composed of a set of nested components, with data flowing through props and state.

    Learning Curve:

    React is considered to have a shallow learning curve compared to some other frameworks like Angular, making it suitable for beginners. The ES6 syntax is generally easier to manage, especially for smaller applications.

    Community Support:

    React has a strong and active community. It is one of the top-rated repositories on GitHub with a large number of stars and a vast ecosystem of libraries and tools. The official documentation is easily accessible, and platforms like Stack Overflow have a massive number of React JS related questions with accepted answers, indicating a highly responsive community.

    Market Trends and Job Opportunities:

    There is a significant demand for React JS developers in the job market. Numerous job opportunities are available across various platforms, and the demand has seen substantial growth in recent years. React developers’ salaries are generally attractive and depend on factors like experience, skills, and location. Top companies like Reddit, BBC, Netflix, Facebook, PayPal, Instagram, Uber Eats, Airbnb, and Twitter use React.

    Testing in React:

    Testing is a crucial aspect of React application development. React’s architecture and one-way data flow make applications highly testable. Unit testing, functional testing, and integration testing are important types of testing. Tools like Jest and Enzyme are popular for React testing.

    Real-Time Projects:

    The sources mention several real-time project ideas that can be built using React, including:

    • E-commerce App
    • Chat App
    • Social Media App
    • Video Sharing App
    • URL Shortener
    • Music Streaming App

    These projects demonstrate the versatility of React in building various types of interactive web applications.

    Becoming a React JS Developer:

    The path to becoming a React JS developer involves learning the fundamental concepts, gaining hands-on experience through projects, and staying updated with the latest advancements. Engaging with the developer community and practicing for interviews are also important steps. Employers often look for skills in JavaScript, HTML, CSS, React core concepts (JSX, components, state, props, hooks), state management libraries (like Redux), build tools (like Babel, Webpack, npm), RESTful APIs, and version control systems (like Git).

    In conclusion, React JS is a powerful and widely adopted JavaScript library for building modern web applications. Its component-based architecture, efficient rendering through the Virtual DOM, unidirectional data flow, and strong community support make it a valuable skill for front-end developers. The demand for React developers continues to grow, offering numerous career opportunities with competitive salaries.

    React JS: Component-Based Architecture Explained

    Let’s delve into the component-based architecture of React JS. As highlighted in the sources, this is a fundamental principle that makes React a popular and efficient library for building user interfaces.

    What is Component-Based Architecture?

    In React, the user interface (UI) is broken down into reusable, self-contained components. Think of it like building with Lego blocks, where each block (component) has its own structure and function, and they can be combined to create a larger structure (the application). Each component manages its own structure and behavior independently.

    Key Characteristics of Components:

    • Reusability: One of the primary benefits is that these components can be reused throughout the application and even in other projects. This “write once, use it anywhere” principle saves development time and effort.
    • Self-Containment: Each component is self-contained, meaning it encapsulates its own logic (how it behaves) and its own view (how it looks). This makes it easier to manage and understand individual parts of the application without affecting others.
    • Independent Functionality: Components can function independently. This allows developers to focus on building and styling one section of the application at a time without breaking other parts.
    • Building Blocks: React applications are essentially trees of components, where smaller components are composed together to form larger ones. There is often a root component at the top, with child and sub-child components forming the rest of the UI hierarchy.
    • Logic and View Separation: Component-based architecture enables the separation of logic and view. This makes the codebase more organized and easier to maintain.

    How Components Work:

    • Rendering: Each component has a render method that returns a React element, which describes what should appear on the screen. This often involves JSX, an HTML-like syntax that gets transformed into JavaScript.
    • Data Flow: Components interact with each other through props (properties) and state.
    • Props are like arguments passed to a function; they are read-only and flow downwards from parent to child components. They allow parent components to configure and control their child components.
    • State is data that is managed within a component and can change over time, triggering re-renders of the component and its children. Only class components can have their own state.
    • Composition: Complex UIs are built by composing smaller, simpler components together. Parent components can embed and manage child components.

    Advantages of Component-Based Architecture:

    • Faster Development: Reusability and independent functionality allow developers to build applications more quickly. Developers can focus on individual components without worrying about the entire codebase.
    • Improved Organization: Breaking the UI into smaller, manageable pieces leads to a more organized codebase that is easier to understand, navigate, and maintain.
    • Increased Reusability: As mentioned earlier, components can be reused across different parts of the application, reducing code duplication and development effort.
    • Enhanced Performance: While the virtual DOM is the primary driver of performance, component-based architecture facilitates targeted updates. When a component’s state or props change, only that component and its relevant children need to be re-rendered.
    • Easier Testing: Individual components can be tested in isolation, making it easier to write unit tests and ensuring the reliability of different parts of the application.
    • Better Collaboration: Teams of developers can work on different components simultaneously without interfering with each other’s code.

    In summary, the component-based architecture in React JS is a powerful paradigm that promotes reusability, maintainability, and efficiency in building dynamic user interfaces. By breaking down complex UIs into smaller, self-contained components, developers can create applications that are easier to develop, understand, test, and scale.

    React’s Virtual DOM: Concepts and Advantages

    Let’s discuss the Virtual DOM in React JS in detail, drawing on the information from the sources.

    The Virtual DOM is a central concept in React that plays a crucial role in its efficiency and performance.

    What is the Virtual DOM?

    • The Virtual DOM is essentially a lightweight copy of the actual DOM (Document Object Model).
    • You can think of it as a tree data structure of plain JavaScript objects.
    • Like the actual DOM, a Virtual DOM is a node tree that lists the elements and their attributes and content as objects and their properties.
    • React’s render function creates a node tree out of the React components.

    The Problem it Solves:

    • Direct DOM manipulation is slower compared to most JavaScript operations. Browsers have to perform several costly steps when the real DOM is updated, including parsing HTML, recalculating CSS, updating layout, and re-rendering the tree.
    • Many JavaScript frameworks update the DOM more than necessary, leading to inefficient updates and performance issues. For instance, updating one item in a list might cause the entire list to be rebuilt.

    How the Virtual DOM Works:

    React utilizes a process called reconciliation to efficiently update the actual DOM. This process generally involves three main steps:

    1. Update in Virtual DOM: Whenever the underlying data in a React component changes (due to state or props updates), the entire UI is re-rendered in the Virtual DOM representation.
    2. Diffing Process: React then compares the new Virtual DOM with the previous snapshot of the Virtual DOM. It figures out the differences between the two versions, identifying which Virtual DOM objects have changed. This process of finding the differences is often referred to as “diffing”.
    3. Patching the Real DOM: Once React has identified the changes, it updates only the necessary parts of the real DOM to reflect those changes. This means instead of re-rendering the entire UI in the browser, React applies a “patch” containing only the modifications.

    Analogy:

    The process of using the Virtual DOM can be likened to editing a blueprint of a house (Virtual DOM) before making changes to the actual house (Real DOM). It’s faster to modify the blueprint than to physically move rooms. Once the blueprint is finalized, you then make only the necessary adjustments to the real structure.

    Advantages of Using the Virtual DOM:

    • Faster Rendering: By minimizing direct manipulation of the real DOM, React achieves faster rendering and improves application performance.
    • Enhanced Performance: The Virtual DOM leads to better performance of React applications, especially for complex and dynamic UIs with frequent updates.
    • Reduced Load Times: Faster rendering has a massive impact on reducing load times and quickly adapting performance based on user traffic.
    • Improved User Experience: By ensuring faster and more efficient updates, the Virtual DOM contributes to a smoother and more responsive user experience.
    • SEO Friendly: While not directly a benefit of the Virtual DOM, React’s ability to perform server-side rendering (SSR), often facilitated by the Virtual DOM concept, can improve SEO. SSR allows the initial rendering of React components on the server, sending a fully rendered HTML page to the browser, which search engines can easily crawl.
    • Cross-Browser Compatibility: The Virtual DOM is not browser-specific and helps in abstracting away browser-specific DOM implementations, leading to more consistent behavior across different browsers.
    • Lightweight: The Virtual DOM itself is lightweight as it’s just a set of JavaScript objects.

    Virtual DOM vs. Real DOM (Source):

    FeatureReal DOMVirtual DOMUpdate SpeedSlowerFasterDirect UpdatesDirectly updates HTMLCannot directly update HTML; updates the Virtual DOM firstElement UpdatesCreates a new DOM if an element updatesUpdates the JSX if an element updatesManipulationMore expensiveEasierMemory UsageCan lead to memory wastageResults in no memory wastageIn conclusion, the Virtual DOM is a key innovation in React that significantly optimizes UI updates by acting as an intermediary between the developer’s desired UI state and the browser’s rendering engine. This abstraction allows React to efficiently manage and apply changes to the real DOM, resulting in faster, more performant, and user-friendly web applications.

    React State Management: Concepts and Techniques

    Let’s discuss State Management in React JS, drawing on the information from the sources and our previous conversations about component-based architecture and the Virtual DOM.

    What is State in React?

    In React, state is a way for a component to hold and manage data that can change over time. It is essentially an object that determines a component’s rendering and behavior. Unlike props, which are passed down from parent components and are immutable within the receiving component, state is local to a component and is mutable.

    • Components can have an initial state defined within their constructor using this.state.
    • State can be updated over time in response to user interactions, network requests, or other events.
    • When a component’s state changes, it triggers a re-rendering of the component and its child components, allowing the UI to reflect the updated data.

    Stateful vs. Stateless Components:

    • React components can be categorized as either stateful or stateless.
    • Stateful components (class components) have the ability to maintain their own state and manage changes to it over time. They inherit from React.Component. As per ES6 standards, class components are the primary way to manage state.
    • Stateless components (functional components), on the other hand, do not have their own state. They primarily receive data as props from their parent components and render UI based on those props. They are essentially pure JavaScript functions. However, with the introduction of React Hooks, functional components can now also manage state.

    Updating State with setState():

    • To update the state of a class component, you should always use the this.setState() method.
    • setState() merges the new state with the old state. This means that if your state object has multiple properties, you only need to provide the properties that you want to update.
    • It’s crucial not to modify the state directly (e.g., this.state.property = newValue) because React may not recognize the change and won’t re-render the component. Direct modification also prevents React from correctly managing state transitions.
    • State updates through setState() may be asynchronous, meaning there’s no guarantee that the state will change immediately. React might batch multiple setState() calls into a single update for performance reasons. Therefore, when calculating the next state, you should not rely on the current values of this.props or this.state immediately after calling setState().

    State and Component-Based Architecture:

    • In a component-based architecture, state is often managed in parent components and then passed down to child components as props. This facilitates the flow of data through the application hierarchy.
    • Child components can then trigger state updates in their parent components through callback functions that are also passed down as props.

    Unidirectional Data Flow and Flux:

    • React follows a unidirectional flow of data or one-way data binding. This means that data flows in a single direction throughout the application, which provides better control over the data.
    • Flux is an architectural pattern introduced by Facebook for managing data flow in React applications. It emphasizes unidirectional data flow through four main components:
    • Actions: Objects that represent events or changes that should occur in the application. They have a type field.
    • Dispatcher: A central hub that receives actions and dispatches them to registered stores. There should be only one dispatcher per application.
    • Stores: Containers for application state and logic. They register with the dispatcher and update their state based on received actions. When a store’s data changes, it emits a change event. Flux can have multiple stores.
    • Views (React Components): Display data retrieved from stores and can initiate actions based on user interactions. Views subscribe to change events from the stores they depend on.

    Redux:

    • Redux is a popular open-source JavaScript library for managing application state, often used with React. It implements the principles of Flux but with some key differences.
    • Key Principles of Redux:Single Source of Truth (Store): The entire application state is stored in a single store.
    • State is Read-Only: The only way to change the state is by dispatching actions.
    • Changes are Made with Pure Functions (Reducers): Reducers are pure functions that take the previous state and an action, and return a new state. They determine how the state should change based on the action type.
    • Redux provides a more structured approach to state management, especially for complex applications.

    React Hooks for State Management:

    • Introduced in React 16.8, Hooks allow you to use state and other React features in functional components.
    • useState is a fundamental Hook that enables functional components to have their own state variables. It returns an array with the current state value and a function to update it.
    • useReducer is another Hook used for more complex state management, similar to how Redux manages state. It takes a reducer function and an initial state, and returns the current state and a dispatch function to trigger state updates.

    Context API:

    • The Context API is a React feature that provides a way to share values like themes, user authentication status, etc., between components without explicitly passing props through every level of the component tree (prop drilling).
    • You can create a Context object using React.createContext() and then provide values to consuming components using a Context.Provider. Components can then access these values using the useContext Hook or a Context.Consumer.

    State Management and the Virtual DOM:

    • When the state of a component changes and a re-render occurs, React creates a new Virtual DOM tree.
    • The diffing process then compares this new Virtual DOM with the previous one to identify the minimal changes needed to update the actual DOM.
    • Efficient state management ensures that only the necessary components re-render when their relevant state changes, which optimizes the performance benefits of the Virtual DOM. Techniques like state collocation (keeping state close to where it’s needed) can further enhance performance by reducing unnecessary re-renders.

    In summary, state management in React is a critical aspect of building dynamic and interactive user interfaces. React provides built-in mechanisms like the state property and the setState() method in class components, and Hooks like useState and useReducer in functional components. For more complex applications, state management libraries like Redux, or the Context API for global data sharing, offer more structured solutions while still leveraging React’s component-based architecture and the efficiency of the Virtual DOM.

    React Router Navigation in Single-Page Applications

    Let’s delve into React Router navigation, drawing upon the information from the sources, particularly sections of “01.pdf”.

    What is React Router?

    React Router is a powerful standard library system built on top of React. It is used to create routing in React applications. Its primary purpose is to enable navigation among different views or components in a single-page web application (SPA). Without React Router, displaying multiple views and updating the browser URL accordingly in an SPA would be challenging. React Router keeps the browser URL in sync with the data being displayed on the web page.

    Key Components of React Router:

    React Router provides several essential components that facilitate navigation:

    • BrowserRouter (or aliased as Router): This is a router implementation that utilizes the HTML5 history API (pushState, replaceState, and popState events) to keep the UI synchronized with the URL. It’s the parent component that typically wraps your application and makes the routing functionality available to its descendants. In the provided example, BrowserRouter is imported and aliased as router: import { BrowserRouter as router, Route, Link, Switch } from ‘react-router-dom’;.
    • Route: This component is conditionally shown. It renders a specific user interface (component) when its path prop matches the current URL. The exact prop can be used to ensure that the route only matches when the path exactly matches the URL. For instance, <Route exact path=”/” component={Home} /> will only render the Home component when the URL is exactly /.
    • Link: This component is used to create links to different routes within your application. It functions similarly to the HTML <a> tag but prevents a full page reload, providing a smoother navigation experience in an SPA. The to prop of the Link component specifies the path to navigate to. For example, <Link to=”/about”>About Us</Link> creates a link that, when clicked, will update the URL to /about and potentially render the component associated with that route.
    • Switch: This component is used to render only the first Route that matches the current URL, rather than rendering all matching routes. This is useful when you have multiple routes that might partially match the same URL, and you want only the most specific one to be rendered. All Route components are typically wrapped inside a Switch component.

    How Navigation Works with React Router:

    1. You wrap your application’s main component with a router component like BrowserRouter.
    2. You define different routes using the <Route> component, associating a specific path with a React component that should be rendered when that path is matched.
    3. You use the <Link> component to create navigational links within your application. When a <Link> is clicked, React Router intercepts the click event and updates the browser URL without causing a full page reload.
    4. The router then compares the updated URL with the defined routes.
    5. If a match is found, the component associated with that Route is rendered within the application. The <Switch> component ensures that only the first matching route is rendered.

    Types of React Routers:

    React Router provides different types of routers to suit various needs:

    • BrowserRouter: Recommended for most web applications. It uses the HTML5 history API for clean URLs (e.g., /about).
    • HashRouter: Uses the hash portion of the URL (e.g., /#/about). It’s often used for supporting legacy browsers or when you don’t have control over the server configuration to handle regular URL routing.
    • MemoryRouter: Keeps the URL changes in memory, not in the browser’s address bar. It’s useful for testing and non-browser environments like React Native.

    Advantages of Using React Router:

    • Provides a synchronous URL in the browser with the data displayed on the web page.
    • Maintains a standard structure and behavior for navigation within the application.
    • Essential for developing single-page web applications where content updates dynamically without full page reloads.
    • Enables navigation among views of various components in a React application.
    • Allows changing the browser URL and keeps the UI in sync with the URL.
    • Uses the <Link> component for internal navigation, similar to the HTML <a> tag but without page reloads.
    • The Switch component helps in rendering only one matching route.
    • It’s not necessary to manually set the browser history.

    In the example provided, a basic navigation structure is implemented using BrowserRouter (aliased as router), <Link> components for “Home”, “About Us”, and “Contact Us”, and <Route> components within a <Switch> to render the corresponding components (Home, About, Contact) when their respective paths are matched. This demonstrates the fundamental principles of React Router navigation in action.

    ReactJS Full Course10 Hours [2025] | Learn React js | React.js Training for beginners | Edureka Live

    The Original Text

    hello everyone and welcome to this comprehensive full course on react GS react GS is a popular JavaScript library developed by Facebook for building Dynamic and interactive user interfaces it is widely used for creating single page applications where seamless performance and efficient UI updates are crucial so known for its component based architecture reactjs allows Developers to build reusable UI elements making development faster and more organized so whether you are a beginner stepping into web development or an experienced developer looking to expand your skills reactjs is an essential tool in today’s web ecosystem known for its flexibility and efficiency reactjs Powers some of the most dynamic and interactive web applications today so in this course we will guide you through the fundamentals of react GS its key features and the skills required to become a proficient react GS developer with that said let’s outline the agenda for this react GS full course so first we will start by exploring introduction to react GS where we will understand what react GS is what its purpose and why it’s widely used in modern web development next we will dive into reasons to learn reactjs where we will discover why reactjs is valuable skill and how it can boost your career followed by the features and prerequisites and then we will will explore aspects and advantages of react GS where we will understand the unique benefits that react GS brings to web development moving on we will cover reactjs fundamentals to learn about components jsx and The Core Concepts that form the foundation of reactjs next we will discuss conditional rendering in react GS in this section we will understand how to render content conditional based on different states after that we will dive into react components and react life cycle where we will explore component structures and life cycle methods for better app control then we will move on to react router where we will learn how to manage navigation and routing in react applications next we will explore react hooks understand the power of hooks for managing State and side effects we will continue with reactjs Redux to master State Management in react application using RS next we will compare react versus react n to explore the key differences between react Gus for web and react native for mobile development then react versus angular where we will understand how react GS Compares with angular in terms of performance and structure then we will move on to react GS projects where we will get hands-on experience with practical reactjs projects next we will explore testing in react in this section we will learn how to write and run effective test for your react applications and finally we will conclude with how to become a reactjs developer to discover the road map skills and resources you need to Kickstart your career as a reactjs developer followed by the react GS interview questions where we will prepare for frequently Asked interview questions to boost your confidence and secure job opportunities but before we begin please like share and subscribe to our YouTube channel and hit the Bell icon to stay updated on the latest content from edu Rea also edu rea’s reactjs training course equips you with the skills needed for professional web development roles focusing on improving uiux using this powerful JavaScript library this course covers key react fundamentals including jsx props State events reducers actions and the state tree master these Concepts to build modern web applications confidently so check out the course and enroll today also check out edureka’s full stack development course with certification this course is designed to take you from the basics to Advanced web development covering everything from HTML CSS and JavaScript to powerful Frameworks like react nodejs and express along with API integration and MySQL for database management so check out the course Link in the description box below now let’s get started with our first topic that is Introduction to reactjs Let’s dive into the three major reasons to make react so useful so the first one is component based architecture in react component based AR architecture UI is broken down into reusable self-contained components each component has its own structure and behavior in this layout the page is divided into different parts a navigation bar at top a side bar at right and the main display area in react we build each of these sections as individual components meaning each one can function independently so the next one is virtual Dom the virtual Dom is essentially a lightweight copy of actual Dom instead of directly making changes to the real dor every time something updates react Updates this virtual dor First Once react has figured out what has changed it then updates only the necessary parts of the real Dom and after that we have the development speed react component structure allows us to quickly build into small parts of the app individually since each component is separate we can focus on building and styling one section at a time without breaking other parts of the page this saves the time and help us to build application faster so in short react component structure development speed and virtual Dom help us to create Dynamic efficient and userfriendly applications so now let us move on to what is react first of all react is a open- source JavaScript library react is maintained by developers worldwide and is focused on building user interfaces making it highly adaptable and Community Driven the next one is react makes develop vment fast scalable and simple react component based architecture allows developers to break uis into reusable Parts speeding up the development and making the large application easier to manage next is react is used for building user interfaces mainly single page applications react is perfect for single page applications where content updates dynamically without reloading the entire page offering a smooth user experience and the last one is rea react enables data changes without reloading the page with features like virtual Dom react efficiently updates the data in real time allowing the web applications to respond quickly without full page reloads now let us have a look on trending Frameworks so here is the data from stack Overflow and here we can see that reactjs is most trending framework currently so react is the popular choice for developers nowadays now that we have a clear understanding of of what react actually is let us explore why it is a such popular choice among the developers so the first one is virtual dor reacts virtual nor updates changes efficiently without refreshing the whole page making apps fast and responsive the second one is development speed with the reusable components and large community of pre-build libraries react helps developers to build applications quickly next one is stability RAC uses oneway data flow which means change in child component won’t affect the parent component this keeps the app stable and easy to manage the next one is interactive interface react makes it easy to build highly interactive uis which means user can get smoother and more engaging experience the next one is component based architecture react divides the uis into components allowing us to build update and use part independently saving a lot of time and effort the next one is server site rendering rea supports serers side rendering which can improve page load speed and SEO by rendering the content on the server before sending it to the user the next one is simple to use reapp Simple syntax and clear structure make it beginner friendly letting new developers start creating apps quickly the next one is flexible development react flexibility allows it to be used in a variety of projects from small apps to large scale Enterprise applications so now that we have covered the key components of rea let’s move on to setting up your development environment where we are going to download vs code and then we will install nodejs for running react on our systems now to download visual studio code we need to visit the official website of Visual Studio code we are just going to click on this website and then we are going to just click on the download if you’re using Windows you just need to click here in case you’re using Mac you need to click here so I’m using Windows I need to click here so now after the download process you’ll see something like this you just need to click on I accept the agreement next just check these boxes create desktop icon open with code and open with code click on next and finally click on install so that will install Visual Studio code into your system so now after installing vs code into our system we are going to install nodejs and to download nodejs just visit this website nodejs.org and you just need to click on this download the LTS version so now after clicking on the download node GS LTS version you’ll be able to download the exe file so after completing the download process you will see this interface you just need to click on next and I already have node installed in my PC so I’m getting these options otherwise you’ll just get a next option let us say I want to change it and then again you will click on next next and and then you will just get a finish option here so that will start the installation of nodejs so after successfully installing the nodejs what we are going to do is we are going to open our Command Prompt to cross check whether nodejs has been successfully installed into our system or not so for that we need to write one command so the first command is node hyphen V so this right here is telling the version of our nodejs so the next command is npm hyphen V so this is also telling the version npm version that we have installed so by this we know that not GS and npm has been successfully installed into our terminal so what is the next step so next step is to open our vs code and then in vs code we are going to check whether node and npm are working or not so here I am on my visual studio code so I’m going to open my terminal here and here is my terminal so inside terminal I’m going to repeat the commands so the first one was node V that’s it it is showing the version of node and it is successfully working in my visual studio code and then it is npm V so now npm is also working in my visual studio code so now we have successfully installed the vs code and nodejs into our system and now we are ready to create one project so now that react is installed let’s move on to creating our first react app so to create our first react app we are going to open Visual Studio code inside this we are going to open one folder so here I’m going to create one new folder and I’m going to name it as react Dev we’ll just select this folder and now we have access to this folder inside this folder we are going to open the terminal and inside the terminal we are going to create the app so to create the app we are going to use this command that is npx create react app and after this you can provide any name which you want to provide to your app let’s say I’ll provide it as react and then enter and the installation of the dependences will start just write y here and enter so now this will create the react app and add the dependences into my react tab so we need to choose the different project name I’ll just choose npx create react app and let’s say counter that’s it now it should create my project and now this is installing the packages into my folder right here we can see the counter app has been created and the package.json has been added inside it now let us wait till the react app is getting created now here we can see that our first react app has been successfully created the node modules has been added the source components has been added and we can see the package Json and everything is added in our folder so this is how you create your react app and now what we are going to do is we are going to run our react app so for that we can just use CD and the app name that is counter and enter and after this we’ll just start our reaction tab that’s it we are going to launch our react tab so here we can see this is our first react app so by default when you are going to install the react app you are going to see these things so now we are going to make some changes in our react app and then we are going to write the code for hello world so there are some useless files that you need to delete first so inside the SRC you are just going to keep the index.js and app.js rest you can delete and that’s it I’m going to remove the logo also now we are going to make some changes in our app.js so first of all we are going to remove these and then we are going to remove the code inside the return statement and we are going to write one heading here that will be hello world that’s it we are going to save it and we’ll move on to index.js inside index.js first of all we’ll remove all this and then we are going to [Music] remove this and this so now we have going to just save our file and just look at the output so this is the output the code we have written inside the return statement is hello world so this is our first react app we have successfully written our first code in react that is hello world so now what we are going to do is we are going to learn some coree concepts of react and then we will be creating one counter app so now that our first react app is up and running let’s dive into the Core Concepts of react that make building application so powerful and efficient so the core components of react includes components components are the building blocks of react tab each part of your UI is component which can be reused to make development faster and cleaner they help us to break down the complex uis into manageable pieces next on we have jsx jsx is a syntax that looks like HTML but works inside the JavaScript it makes it easier to write the structure of your react component j6 allows you to combine HTML like code with JavaScript functionality in one place next on we have is virtual Dom the virtual Dom is lightweight copy of the actual Dom react uses it to update the UI efficiently by only changing what’s necessary making the app faster this reduces unnecessary operations and improves the performance next on we have a state management state refers to the data that changes in your app react lets you to manage State inside the components so when the state changes your UI automatically Updates this is essential for handling Dynamic data like form inputs or user interactions next on we have props props is basically short for properties these are used to pass data from one component to another helping you make your component Dynamic and reusable they allow you to customize component based on the data that they receive next on we have is event handlers event handlers in react are functions that handles user interactions like click form submissions and more allowing your app to respond to user actions they provide a way to trigger changes in your app based on the user input so now that we have covered the code concepts of react let’s switch to vs code and apply these Concepts in real project we will see how everything works together with Hands-On coding so the first thing again I’m going to do is I’m going to open one folder inside my visual studio code so I’ll just create one more folder naming naming counter I’ll just select this folder and again we are going to create this app so inside our terminal again we are going to write npx create react app counter that’s it so our app has been created now what we are going to do is we are going to move into the app by CD counter that’s it now again we are going to delete the unnecessary things that includes index. CSS logo and these two files we are also going to delete this app. CSS so now we are going to create one more file inside it which will be counter dogs that’s it we are going to work on these three files and again one more file we should create for our styling so it should be style. CSS and that’s it so first of all we will start with counter do GS so by creating this counter. GS we are going to understand the concepts of State props and event handling so what we are going to create is we are going to create an app in which we will increment or decrement the numbers and by creating that we will be understanding the concepts of State Management and properties and event handling so first of all we are going to import the react to use the GSX syntax and Define the react component so it will be import react from react now here we are defining the properties that we are going to use which includes count increment and decrement and along with that one reset so these are the properties that we are passing so basically counter is a functional component that takes the four props which includes count increment decrement and reset these props are passed down from the app component enabling counter to display and manipulate the count value based on the user interaction now the counter component returns GSX that renders diff element with class counter inside this div section the current count value is displayed inside H1 element as a counter count and then we have created these three buttons including increment decrement and reset the increment button triggers the increment function from the properties to increase the count when clicked and after that we have this decrement button so this triggers the decrement function from the properties to decrease the count when clicked and then on we have this reset button this reset button triggers the reset function from the properties to reset the count to zero when clicked now here we can see that each of the button uses onclick attribute to call the function when clicked since increment decrement and reset functions are passed as props from the app component clicking these buttons triggers the respective functions in the app that we are going to write so for example the increment button is clicked the increment is called which increases the count in the app component State this triggers a rerender of counter updating the displayed count so that’s it for the counter. JS and now we are going to create the app.js now here we are on the app.js section so let us have a look on the app.js so for imports we are importing use state from react this hook manages state within the component and after that comes the counter so counter component from counter that we have created this child component will display the counter and the button from the user interaction now again we are importing this style. CSS from the Style app that we have created after this comes the app components so inside the app component UST state zero initializes account State variable with the initial value of zero and after that count holds the current count and set count is a function that updates the value so state in react is persistent across renders meaning count will retain the value until it’s updated by set count and after that comes the event handlers these functions are used to update the count State based on the user actions first of all we have the increment so it increases the count by five each time it is called by executing set count count plus five and then on we have is decrement a decreases the count by one each time it is called and then we have this reset so reset sets count back to zero by calling the set count zero so by defining these functions the component becomes interactive allowing user to modify the state and see the changes reflected in the real time so that’s it for the app.js we’ll just save this file we’ll just save the counter. JS and after that let us move on to the style. CSS so after writing counter. JS app.js and we are just going to keep the index.js as it is we have just excluded the codes those were not necessary so we have already seen those in the first counter app that we created for hello world so now we’ll just save the index.js and for styling. CSS first of all we have just styled the body using the font family display justify content alignment of items height and the background color after that we have styled the app using these styling techniques and then we have styled the counter after that we have styled the button and that’s it we have made the button hover so that’s it for the styling now we have created the counter app here we learned about three concepts the properties the state and the event listeners so these are the three core components that we have learned and now we’ll just save this project and we’ll run our project so here is the counter app that we have created so when we are clicking on increment the count is incrementing by five when we are clicking on decrement it is decrementing by one and after clicking the reset button it is being reset to zero so this is the simple app that we have created using props States and event listeners so now that we have a proper idea about prop State and event listeners we’ll now move on further and we’ll just create our Mario game so before that as we have now understanding about the prop State and event listener so basically what are components so all the files that you can see inside the source are components of the real so app.js is one component counter. GS is one component index.js is one company so again the other core concept of react was GSX so this right here the code that we are able to see is basically jsx syntax so basically this is a JavaScript code but we have written HTML inside the Javascript file so this is called GSX so now we have clarity about the Core Concepts of react first of all the components here are the components then the GSX these are the GSX and after that we have properties these are the properties and then these are the event handlers and we have also seen the State Management so after that we have this styling so that’s it about the increment project and I hope you are clear with the concept of prop St and event handlers so now that we have clear understanding of the concepts of react we’ll be starting our Mario game so let us now understand how we created this Mario game using react so first of all we’ll start with the sources in this there is a section named esset in this we have included the audio font and the images that we are going to use so after this we are going on the section of components so in inside this components we have one section that is atoms in this we have included all the components that are being used in this game for example we are using Birds bricks clouds key message obstacle sun and all so after this we have this molecules in this we have included the footer the loading screen Mario the corrector and the mobile controls again we have included the title and the score so now one by one we are going to have a look on this codes so first of all let us start with birds so inside Birds there is a section of bird dogs so first of all we are importing the use effect and the use state from the react and after that we are importing the bird. CSS from the stylesheet file so first of all here is ready is a piece of state that starts as a false it will later be said to True when the document is fully loaded and after this the use effect hook runs after the component mounts it defines a function set load that sets is ready to true so after that this part checks if the document is ready to fully load it if it is it calls the set load immediately if not it adds the event listener for the load event which will call set load once the page finishes loading the cleanup function removes the event listener if the component unmounts or if the effect runs again at last we have the return statement the component return a diff containing another diff for the birds the class name of the inner diff changes based on the is ready state if is ready is true it adds the class bird animate which likely triggers an animation so that’s it about the bird. GS now let us look at the bird. CSS so for that first of all we have provided this GF and then we have included the background repeat as no repeat background size height right width position top and left then we have provided the bird animation and after that we have provided the key frames and media queries so that we are already familiar with what are key frames and media queries so now after bird. JS we have bricks. Js so again in bricks. JS the component Imports the use effect and use state from react to handle the state and a life cycle events so it also Imports the CSS file . CSS to style the components and after that we have this const is ready so here is ready is a piece of state initialized to false the state will eventually determine whether the animation of the brick is active or not after that we have is use effect the use effect hook runs when the component mounts it defines the function set load that sets is ready to true and after that we have this LL statement this part checks if the document is fully loaded and if it is document. ready state is complete it immediately calls set load if the document is not loaded yet it adds an event listener for the load event which will call set load once the page finishes loading the cleanup function removes the event listener if the component unmounts or if the effect runs again and after that we have this return statement the component returns are div with a class bricks container inside it there is another diff for the bricks the class name of this inner diff changes based on the is ready state if is ready is true it adds a class brick animate which likely triggers the animation so after this brick. JS we move on to brick. CSS so again in brick. CSS we have given this background image and The Styling that we have included is background repeat background size height width position bottom and lift next on we have brick animate these are the animation that we have provided and after that the key frames and the media queries so now after birds and Bricks let us move on to the clouds so again in cloud. Gs we have included all these functions just like brick. JS and cloud. JS so you can just pause this and go through the code again it is basically the same function we are just importing the cloud. CSS and we have changed this return statement so after this again we have cloud. CSS we have included the background image background repeat background size height width position top and left again we have included the Cloud’s animation and key frames and media queries you can just pause this video and go through the code once and if you have any doubt you can just comment in the comment section after that we have this key message JS inside this key. JS for first we have imported the key message. CSS for The Styling so inside this we have basically created one press container and we have given two paragraphs including Enter key and space key so here Enter key is for starting the game and space key is for jump so after that we have included obstacles so now let us look at the obstacle dogs code so inside this obstacle. JS first of all the component Imports the CSS styling images for the obstacle and necessary hooks from the react it also Imports Redux Hook from the state management so after that dis patch is used to send actions to the Redux store is playay and speed are selected from the Redux state where is playay indicates if the game is running and the speed represents the current speed of the game so now after that we have this use effect that sets up the interval that runs every 100 milliseconds it dispatches action to update the redu store from the current dimensions and positions of the both obstacles by accessing their boundaries rectangles through the Rifts each property height left top width are getting updated from the both obstacle so after that we have one more use effect so this use effect runs whenever the speed value changes if the speed is non- negative it sets the time out to adjust the speed to the small value after 1 second this could be used to ensure that the game continue to run smoothly so after that we have this return statement the component returns a container of the obstacles each obstacle is represented as a image this class name changes based on the isplay state adding moments classes if the game is active the style props adjust the animation duration based on the speed making the animation faster or slower depending upon the game’s current speed so that’s it about the obstacle dogs now we’ll move on to the obstacle. CSS so here we have provided some basic styling techniques to obstacle container obstacle 1 2 and then we have separately styled the obstacle one and two and then obstacle one move then obstacle two move then we have provided some key frames and media queries so again if you have any doubt you can just comment down in the comment section and rest you can pause the video and look at the code so after this all we are left with the Sun so we are importing the sun. CSS for The Styling and we have included one class container Sun container and then we have given the class name as Sun so again inside the CSS we have provided the background image of the sun which is a gif form and then we have provided The Styling that includes background repeat background size height width position top and right and again we have included some media queries into it so that’s it about the atom section now we’ll move on to the molecules so inside molecules what we have done we have created footer loading screen Mario the corrector score and the title so now we’ll just quickly look to the every molecule so before moving on to the molecules we have just imported everything that we have created Birds bricks clouds key messages obstacles and Sun so before moving on to the molecules here we have imported all of these things so each Line Imports the component of specific file path for example bird component is imported from the birds file the imported components are presumbly react components that will be used in the application to render the different parts of the UI and after that this line exports all the imported components into single object by doing this it allows other modules to import any of these components easily from one Central File instead of importing each of them individually from their respective files so now first of all let us look at the Mario character development so here the component Imports style images or the Mario character audio files for jump death sound and various hooks from the react and reds so after that this used dispatch hook allows dispatching actions to the redex store several State values are selected from the redex store to manage the game State such as whether Mario is dead the game is loading or the Mario’s position and the Dimensions now after that these selectors retrieve the position and dimension of two obstacles allowing for the Collision detection now after that we have this audio handling for this we are using use memo hook to create audio objects for jump die and background music this ensure that these objects are only created once optimizing the performance now after that this handle key function listens for the key presses if the enter key is pressed the G is isn’t playing it dispatches an action to set the game as ready and if the space key is pressed while Mario is not jumping that triggers the jump and plays the jump sound after 400 milliseconds it stops the jump sound and resets its playback time so after this right here you can just pause and have a look at the code 1 by one and if you have any doubt you can just comment in the comment section below so after this we have again used this use effect that mon the Mario’s position and checks the collision with the both obstacle so now if the Collision is detected it dispatches the action to set Mario as dead and plays the dead sound it also repeats the game score after the short delay so that’s it about the Mario character and you can just go through the code line by line this code just shows the use of use effect and how we are controlling the Mario and when the Collision is happening to change the state of the Mario and everything so now let us quickly look at the CSS of Mario so here for Mario we have given the styling technique which includes width height position bottom and left then we have animated the jump and then we have added the key frame and then we have added the animation if Mario dies and key frame again for that and we have added some media queries so now after the Mario character development let us quickly look at the footer section so this component Imports the CSS file for styling which would typically Define how the footer looks and after that this defines the functional component named footer functional components are simpler way to create the components in the react and after that we have this return statement inside this div it displays the text copyright followed by the current year which is dynamically obtained from the new date get full year this ensures that the copyright year is always up to the date without the manual change it also includes the anchor tag that links the placeholder the target blank attribute makes the link open in the new tab and then R adds the security feature to prevent the new page from the accessing the previous ones and that’s it for the footer section now this line basically exports the footer component as a default export of the module making it available for import in the other files so that’s it for the fooo section JS now this is the pH section CSS we have just styled the copyright button and the copyright link so now after the foter design let us look at the loading screen so inside the loading screen first of all we have added the import statements this Imports necessary hooks use effect and use state from the react the Mario character image CSS for styling and Redux function set loading screen and use dispatch so now after this we have added this this basically declares the functional component named as loading screen so now after that we have used is ready so is ready is the state variable initialized to false if it will set to True after the specified delay indicating that the loading is complete so again dispatch is a function from Redux that allows the component to dispatch actions to the store and after that we have use the use effect this use effect runs once when the component mounts due to the empty dependency array it sets the timer for 5 seconds after which it updates is ready to True indicating the loading is completed and then at last we have the return statement the component renders a div with the class loading screen container it displays the Mario character image using the image tag while is ready is false it shows an H1 element with the text loading once is ready is true it displays the enter button when the button is clicked it dispatches the set loading screen false action likely to update the global Redux state to hide the loading screen and then at last we have this export default loading screen so that’s it for the loading screen now let us look at the CSS of the loading screen so inside the loading screen CSS we have provided width height position top left bottom right background color color display Flex Direction justify content alignment of items Gap and Z index then we have styled the Mario loading then the loading title and then the enter button after that we have provided this hover effect to the enter button so that’s it you can go through the code line by line and again that is it for the loading screen so now let us move on to the mobile controls again we have added the Imports here and after that we have added this mobile controls this defines the functional component that is named as mobile controls and after after that we have added this is play Mario jump is die so this indicates if the game is currently being played Mario jump indicates whether the Mario is currently jumping is die indicates if the game is over and dispatch is used to send the action to the Redux store after that we have used use memo to create an audio object for the jump sound this ensures that the audio is only created once for the performance efficiency and after that this function is triggered when the start button is clicked it checks if the game is not already playing and if it is not over if the both conditions are met it dispatches an action to set the game to ready and after that we have created this function this function is called when the jump button is clicked it checks if the Mario is not already jumping and if he isn’t it dispatches an action to set him as jumping plays the jump sound after 400 milliseconds it stops the sound and resets the playback time and at last we have this return statement so in this the component renders the div with the class mobile controls container it conditionally renders the start button when the game is not playing or not over again the over button when the game is over the jump button when the game is playing and at last again we have this export statement and now again we have the styling of mobile controls so here is the media query and then the mobile controls container and after that we have styled the start button jump button and control button again we have styled these button by applying the filters and we have given the background color and then we have given the background color to the control jump button so that’s it for the CSS of mobile controls and the JS off mobile controls you can go through the code line by line and again comment down if there is any doubt now at last we’ll move on to the calculation of the score so now we are at the score. JS again we have added the import statements that Imports the necessary hooks from react Redux function and CSS file so after that we have this declaration this defines the functional component named as score and after that we have used this query selectors for score last score play die and dispatch so the score shows the current score from the RCT store and the last score shows the last score recorded and the play is basically a Boolean indicating if the game is currently being played die is basically a Boolean indicating if the game is over and dispatch is a function that is used to dispatch the action of the Redux store and after that we have included this high score this basically initializes the state variable high score it retrieves the high score from local storage passing it as an integer or defaults to zero if the high score is not found so after that we have used this use effect this use effect runs whenever the dependencies change that means incrementing the score if the game is being played or not over it sets the time out to increment the score by one to every milliseconds and then updating the last score and the high score and after that we have the return statement so this component basically renders the div with the class score container if the game is currently being played it displays the current score if the game is over it displays the last score it always displays the high score along with that and at last we again have the export statement so that’s it for the score. GS and we’ll move on to the score. CSS so for score. CSS we have just applied these styling techniques including the media query and the styling of high score so after that last one we have is title so inside this title. JS first of all the component Imports the CSS file for styling ensuring that the component has desired looks so again after that we have this cons title this basically defines the functional component named as title and after that we have this return statement so the component Returns the div with a class name title container which acts as a wrapper for the title elements inside this div an image element displays the Mario logo it uses the imported Mario image as a source and it has the class Mario logo for styling and H1 element contains the text Mario jump styled with the class title this serves as the main title of the game and again we have the export default title so here is the styling so first of all here we have styled the container then we have styled the Mario logo then title and then we have added the media queries so that’s it for the title now let us quickly go through this index.js file so here each Line Imports the specific component from the corresponding directories so footer displays the copyright information loading screen shows the loading animation and enter button Mario represents the character and mobile controls provide the button for the mobile users score displays the current last and the high score title basically displays the game title and after that this line of code exports all the imported components as named export this means that when importing from this module elsewhere you can access each component by its name so again in the other index .js file we have exported the atoms and the molecules so that’s it we have covered all the atoms and the molecules that we have made for the Mario game so now what we are going to do is we are going to run our project so for running our project we are just going to add the command and then we’ll be able to run our project so here we are going to add the command to run our project so we are just going to write that’s it we are going to give the command as npm start and it will start our project so here is our game here is the output of our Mario game it is the landing page we can just click on enter and it is basically the screen here we have the enter key we have to press the enter key to start the game and then we have to press the space key to jump here we calculate the score the high score we have added these GIS deps of birds clouds sun and the bricks and here we have the Mario character so here is the footer basically we have designed the copyright and this is the title so this is the whole project that we have created using the react so I’ll just quickly enter key and now I can see the game has been started so again I can jump using the space key and my score is being calculated here my current score and the high is being calculated here so this is the final project that we have created using [Music] react starting with the first reason to learn react which is react is easy to learn most developers love react because it is efficient declarative and flexible what is even more important and exciting is that learning react is easier than learning other JavaScript Frameworks if we compare react with angular on learning basis react is a library and a complete solution that is built around one main concept which is to give you more freedom in how you use the library to compose and organize your own component based architecture while angular in turn is more like Constructor or a tree of components so you need to understand how its elements behave work and combine together nevertheless react’s relative Simplicity does not not purely depend on its file structure and component model but also making the code easier to understand and launch of course react doesn’t burden developers with too many things to be mentally Managed IT generally does have a simpler file tree and flexible component model but also that’s a significant benefit react tends to have a substantially shorter dependency list while angular’s dependencies from a dising set that’s problematic to track react aims to make develop life easier by considerably shortening the equivalent lists the more difficult a technology is to learn the longer it takes to start the development process therefore a steep learning curve is one of the main reasons why react has gained so much traction in such a short time given react Simplicity businesses today are more inclined to use it thus building their projects faster now moving towards the second reason to learn react that is increased job opportunities there are thousands of jobs in the world which demand react GS skills there are more than 43,000 jobs available on LinkedIn alone in India for react as compared to 2019 there has been 184% of increase in the openings for rad GS developers in the year 2020 according to India Today a quest report States after cid9 reactjs developer is one of the top digital skilled jobs in demand this quite a huge number of job opportunities makes react one of the skills most of the application developers want to learn and secure a good job third reason to learn react could be attractive pay scale of course salary is important today react has the best pay scale on most of the job suggesting websites like LinkedIn glass door Etc talking about the salary Trends in India the current average salary for roles of react domain is 735 5K which includes the average salary of 597k for frontend developer or engineer the average salary of 654k for software engineer and the average salary of 1 million for senior software engineer now this could be a major reason to learn react because money actually matters in professional career the next reason to learn react is easy migration most of the communities that were not aware of reactjs are now migrating to the reactjs as it is very easy to understand and Implement they have started rewriting the code on react some top companies like Reddit BBC Netflix Facebook as PayPal instacart Uber Eats Airbnb Twitter OK Cupid Netflix Etc are using react this increases the job requirement of react skills in the world a lot of successful and big organizations dare to migrate on react because react provides the facilities which help in Migra ation easily as mentioned in react documentation when react deprecates a pattern they study its internal usage at Facebook and add deprecation warnings which let them assess the impact of the change sometimes they back out if they see that it is too early and they need to think more strategically about getting the code bases to the point where people are ready for the change if they are confident that the change is not too disruptive and the migration strategy is viable for all cases they release a deprecation warning to the open-source Community they are closely in touch with many users of react outside of Facebook and they monitor popular open-source projects and guide them in fixing those deprecations given the sheare size of the Facebook react code base successful internal migration is often a good indicator that other companies won’t have problems either nevertheless sometimes people point out additional use cases they haven’t thought of and they add Escape hatches for them or rethink their approach react not only cares for the migration from other technology but also from older version of react itself to the newer version of react they don’t deprecate anything without a good reason they recognize that sometimes deprecations warnings cause frustration but they add them because deprecations clean up the road for the improvements and new features that they and many people in the community consider valuable for example a warning about unknown Dom props in react 15.2.2 was added many projects were affected by this however fixing this warning is important so that they can introduce the support for custom attributes to react there is a reason like this behind every deprecation that react adds when they add a deprecation warning they keep it for the rest of the current major version and change the behavior in the next major version if there is a lot of repe manual work involved they release a Cod Mod script that automates most of the changes code mods enable us to move forward without stagnation in a massive code base and they encourage you to use them as well so that’s how react helps in migration the next reason to learn react is reusability which is a boon for developers react doesn’t require big lines of quotes to program an application in react we say that everything is a component a user writes small codes called components and combines them to form another component simply any app made with react is a tree of components react follows write ones use it anywhere principle for example if we are building an Instagram app using react Jus we will have many components like a separate component for navigation another one for the story section also for news feed then for profile and all other section of the application components are basically like functions the word has seen a big jump in the increment of the number of developers switching to react JS for which reusability of code plays a vital role moving to sixth reason to learn react which is data binding data binding is the process of synchronizing data between the model and view there are two basic implementations of data binding one directional and twood directional react uses oneway data binding which doesn’t allow child elements to affect the parent elements when they are updated this makes code more stable and easier to debug this also makes the code predictable and ultimately improves the performance of the application if we compare react data binding approach with any other JavaScript framework let’s take angular angular uses two-way data binding to connect the Dom values to the model data this makes it simpler to work with but also has a negative impact on performance it makes it slower when the application deals with lots of data requests it also makes debugging difficult and results in less predictability another reason why you should use react is its flexibility that manifests itself in a number of ways flexibility is especially visible when it comes to the use of react for web development web development projects tend to grow into bulky systems that may be difficult to fix or enhance first when we talk about reacts flexibility we refer to the libraries innate modularity as we know reacts architecture allows bundling front-end code into custom components this providing a solid foundation for the overall development process optimization the react’s position on the scale of opness is a stable the library neither locks nor guides you into their way of doing things on the one hand it dictates how you should create reusable components on the other hand it gives a free hand to decide how to handle routing and testing our organized dependencies and more this degree of Freedom can turn out confusing for newcomers initially but with time working in a react development environment becomes a pure delight for developers this way react allows you to write clean modular code breaking the project into separate components as a result when code is modular it gets easy to maintain and scale second react is super flexible in the sense that it can be integrated with other third party libraries and MVC Frameworks you can choose to create a react project from scratch or gradually introduce react to your existing literacy code base creating a new react app is not too difficult embedding react components one by one into your code written using other Technologies is not a problem as well and vice versa it’s really relatively easy to integrate third party libraries into react applications so using react for front end is a great choice besides while we are on the topic of flexibility it should be noted that another significant advantage in the ease of transfer and support of react native apps react native is actually a framework for building native apps using react so if you know how to develop applications using react you are already well on your way to getting well worsed in react n to they are conceptually similar most of the react Concepts transfer to react native thus you can waste no time learn react native and start developing mobile applications for IOS and Android with a native look and feel if we compare react and angular on this as I have discussed just now react gives us the freedom to choose the tools architecture and libraries for developing an application on the other hand angular offers a limited amount of freedom and flexibility now let’s see the E reason to learn react that is fast rendering react is a client side JavaScript library that uses server side rendering why is it a benefit enhanced support for serers side rendering tones react into a robust performance oriented solution for creating content focused applications be it a web application or native rendered applications for Android and iOS react has everything for a brilliant performance faster rendering has massive impact on reducing load times and quickly adapting the performance in real time based on user traffic flow it’s common knowledge that the faster the page load is speed the more users won’t leave the website and will use your service or purchase your product this is crucial for online business and after covid-19 online businesses have seen a new Milestone react’s virtual Dom is basically the prime cause of faster rendering and better performance of react apps first of all the react virtual Dom that is virtual document object model can be understood as a tree data structure of plain JavaScript objects accordingly react’s advantage over other Frameworks is that it creates virtual Dom as a copy of the real Dom and whenever the state change in a react component happens it reenders the virtual Dom first compares the old version to the new one and eventually only the required minimum is changed in the real Dom instead of re-rendering the entire UI reacts virtual Dom serves as a layer between how things are supposed to look and the actual processes happening to render all of these things onto the page now let’s move to the ninth reason to learn react that is easy debugging when something goes wrong it is important that we have breadcrumbs to trace the mistake to its source in the code base in react props and state are those breadcrumbs if you see something wrong on the screen you can open react da tools find the component responsible for rendering and then see if the props and state are correct if they are you know that the problem is in the component render function or some function that is called by render function the problem is isolated if the state is wrong you know that the problem is caused by one of the set State function calls in this file this two is relatively simple to locate and fix because usually there are only a few set State function calls in a single file if the props are wrong you can Traverse the tree up in the inspector looking for the component that first Poison the Well by passing bad props down this ability to trace any UI to the data that produced it in the form of current props and state is very important to react it is an explicit design goal that state is not trapped in closures and combinators and is available to react directly while the UI is dynamic we believe that synchronous render functions of props and state turn debugging from Guess work into a finite procedure we would like to preserve this constraint and react even though it makes some use cases like complex animations harder react results in not only easily debuggable code but also highly testable applications react itself makes it easier to create a clean architecture that is friendly to testing if you are working with react we don’t have to do any extra configuration of UI tests instead we can use justest that is basically Facebook’s JavaScript test Runner that is configured right out of the box and works seamlessly with reactjs applications if we choose to develop a new application using Create react app just will go with it by default so we will be able to execute tests rapidly just as a node based Runner therefore while testing a reactjs application a developer can run unit tests in a node environment not in real browser by mocking components under test traditional UI test execution tends to be slow but with react UI tests are run quite faster UI tests often end up being brittle however by separately testing single react components in a node environment we can avoid flakiness and ensure test results reliability this is because in such a way we will be in the position I to test pure functions which unlike with traditional endtoend UI tests is much less time consuming both in terms of writing and maintenance if we are running unit tests using react we can be sure that it won’t be a big challenge to write these tests quickly and update them easily now here strong documentation and community support for react becomes the final 10th reason to learn react being an open-source Library reactjs has what it takes to keep attracting more and more newcomers to its Community which makes it stronger over time the feeling of belonging to a community is a solid base that a software developer can rely on when learning new technology or working on a complex project as react developer you will definitely get this feeling the react library has once gotten into the growth Loop and seems to intend to remain there as long as possible as of today reactjs is one of the five top rated repositories on GitHub with over 170k stars and over 5 million applications publicly admitting to using it react has a rich ecosystem to benefit from or contribute to besides finding one’s way around all this information won’t be a big challenge as the react documentation can be easily found on the official website the community is active so you can get rapid feedback or response to your inquiry once you feel stuck currently on stack Overflow there are over 14 million questions tagged react JS that have at least one accepted answer that’s incredible how responsive the community is so once you encounter a problem chances are someone has already had the same problem and there is a solution to it so that you will only have to copy paste it from the corresponding discussion thread with this I have covered top 10 reasons to Lear nonreact last but not the least I want to say traditionally open-source projects get along without full-time developers and are being improved through the work of independent contributors who are committed to the project to a certain degree but reacts contributors commitment is much deeper than that which has a direct positive impact on react developers coding [Music] experience Js X jsx stands for JavaScript XML it’s an XML or HTML like syntax used by react it extends the ecma script so that XML and HTML like text can coexist along with JavaScript react code this syntax is used by the pre-processors like Babel to transform HTML like text found in JavaScript files into standard JavaScript objects with jsx we can go a step further by again embedding the HTML code inside the JavaScript this makes HTML codes easy to understand and boosts javascript’s performance while making our application robust a virtual dor like an actual dor a virtual dor is also a note tree that lists the elements and their attributes and content as objects and their properties react’s render function creates a not tree out of the react components it then Updates this tree in response to the mutations in data model caused by various actions done either by the user or by the system itself the virtual Dom basically Works in three steps first whenever any of the underlying data changes the entire UI is rendered in the virtual Dom representation then the difference between the previous domor representation and the new one is calculated once the calculations are completed the real Dom will be updated with only those changes that have actually been made you can think of this as a patch in a virtual dorm the changes are applied only to those Elements which have actually changed or updated this will not just make our application faster but also there is no memory vage testability react views can be used as functions of the state here state is basically an object which determines how a component will render and behave thus we can easily manipulate with the state of the components which we pass to The reactjs View and take a look at the output and triggered actions events functions Etc this makes react applications quite easy to test and debug server side rendering or SSR server side rendering allows you to pre-render the initial state of your react components at the server side itself with SSR the server’s response to the browser becomes only the HTML of the page which is now ready to be rendered thus the browser can now start rendering without having to wait for all the Java script to be loaded and executed as a result the web page loads faster here the user will be able to see the web page in spite of react still downloading the JavaScript creating the virtual domor linking events Etc at the back end oneway data binding unlike other Frameworks reactjs follows the unidirectional data flow or one-way data binding A major advantage of one-way data binding is that throughout the application the data flows in a single single Direction which gives you better control over it because of this application state is contained in specific stores and as a result rest of the components remain Loosely coupled this makes our application more flexible leading to increased efficiency Simplicity the use of jsx files makes the application really simple easy to code and understand as well even though you can use plain JavaScript over here using jsx is much easier react’s component based approach along with the distinct lifestyle methods also makes it very much simple to learn so that was about the features of react okay so now that you’ve understood the features of react let’s move on and take a look at the prerequisites that are required in order to learn react the first and foremost prerequisite is HTML HTML stands for hypertext markup language and it is the standard markup language for creating web pages and web applications a markup language is a computer language that is used to apply layout and formatting conventions to a text document markup languages make the text more interactive and dynamic it can also turn text into images tables links Etc the next prerequisite that you will need to know is CSS CSS basically stands for cascading style sheets CSS is a technology that is proposed and developed by the worldwide Web Consortium or the w3c for short it was released to help free web developers from the tedious process of inline styling and make styling a separate entity in itself next up is Javascript JavaScript is a lightweight interpreted programming language with objectoriented capabilities that allows you to build interactivity into otherwise static HTML Pages the general purpose core of this language has been embedded in Netscape Internet Explorer and almost all of the web

    browsers following JavaScript is npm npm stands for node packet manager it is the default packet manager of node.js that is completely written in JavaScript it was developed by ISAC zutter it was released in 2010 and since then it is responsible for managing all the nodejs packages and modules npm is the world’s largest software registry which is completely free and open- sourced developers all over the world make use of npm for sharing software code editors or Ides code editors and Ides are integrated development environments are platforms where programmers write their code and produce their final products some examples are Sublime Text atom Visual Studio code Etc so basically if you want to write your react code you will need to make use of any of the code editors or IDs okay so now moving on towards the next topic which is the react architecture as mentioned earlier react is the v in the MVC architecture the M or model architecture is provided by flux plux is an architectural pattern that enforces a unidirectional data flow it controls derived data and enables the communication between multiple components using a central store which has authority over all the data any update in data throughout the application must occur here itself plux provides stability to the application and reduces time errors so now let’s take a look at some of the important Concepts in react the first thing that you should be aware of is components in reactjs everything is a component if you guys remember I’ve already given the one Lego House application example earlier on in this session just like the Lego blocks are combined together to make a single structure components and react are integrated together to build one bigger and dynamic application so therefore in react the entire application can be modeled as a set of independent components these components basically serve different purposes components also enable us to keep the logic and the view separate in react multiple components are rendered simultaneously State and props state is the heart of react components they are basically the source of data and must be kept as simple as possible basically states are the objects which determine the component rendering and behavior they are mutable and can create Dynamic and interactive components States in react are accessed via this state function states also have something called as state life cycle so basically we need to initialize resources to components according to the requirements this is called as mounting in react it is critical to clear these resources taken by components whenever they are destroyed this is done in order to manage the performance and is called as unmounting in react it is not essential to use State life cycle methods but you can use them if you wish to control the complete resource allocation and retrieval process props props is the Shand for properties in react they are readon components that must be kept Pure or immutable props are always passed down from the parent to the child components throughout the application so therefore all the user needs to do is change the parent component State while the changes are passed down to the child component through props on the other hand a child component can never send a prop back to the parent component this helps in maintaining the unidirectional data flow and is generally used to render the dynamically generated data keys keys in react provide identity to components keys are the means by which react identifies components uniquely while working with individual components we do not require key as react takes care of key assignment according to their rendering order however we need a strategy to differentiate between thousands of elements in a list so this is where Keys come into picture if we need to access the last component in a list using keys it saves us from traversing the entire list sequentially Keys Also Serve to keep a track of which items have been manipulated they should be given elements inside the array to give elements a stable identity debugging in react now there will be a point when a developer goes through a roadblock it could be as simple as a missing bucket or as tricky as segmentation Falls in any case the earlier the exception is caught the Lesser is the cost overhead react uses compile time debugging and detects errors at an early stage this ensures that errors don’t silently turn up at the run time Facebook’s unidirectional data flow allows clean and smooth debugging fewer stack traces lesser clutter and an organized flux architecture for bigger applications event handling and manipulation of State whenever an event such as a button click or a mouseover occurs we need to handle these events and perform the appropriate actions this is done using event handlers so those were some of the important concepts of react that you should know when you’re learning react so now talking about the learning curve of react react unlike angular has a shallow learning curve and it is very much suitable for beginners the es6 syntax is easier to manage especially for smaller to-do applications in react you code in the JavaScript Bay giving you the freedom to choose your tool depending upon your need on the other hand angular expects you to learn one additional tool that is typescript which can be viewed as the angular way of doing things in angular you need to learn the entire framework if you’re just building a simple UI application now let’s move on so once you’re done with learning the basic concepts of react you’ll have to adopt the project-oriented learning approach this is because whenever you create a project you will have a 360° learning this is because when you create a project you will have to do everything by yourself therefore you’ll make use of all the programming Concepts resulting in better understanding and implementation remember that you do not have to master the world in your first project itself so start off by choosing a very simple one complete it by yourself and try your best not to copy anything from anywhere else as you proceed you can take a bigger applications and work on them it is sure that you will face difficulties while making your applications however it comes with a reward of learning if you are stuck at some point in your project try to break down your problem into minor parts and then work on each of them one at a time now once you’ve decided to learn react remember that you’re not alone there are a number of developer communities that will help you along the road in this session I’m going to be discussing about GitHub stack Overflow and edura Community GitHub as many of you would be aware of is the world’s leading software platform that brings together developers from all over the world it allows you to build your programs share your work or discover what you are looking for you can also engage with other programmers by asking them your doubts Etc stack overflow stack Overflow is another open community that entertains anyone who wants to code it will provide you with some of the best answers for even the most trickiest questions and errors and will also help you share your knowledge with others using stack Overflow not to forget if you have any doubts or queries regarding any of the Technologies you guys can also check out the edura community website and get all your queries answered by experts also make a note that a key to remember what you learn is to share so make sure you share what you learn with others last but not the least stay updated technology sees New Heights every day the version that you learn today will get modified in the upcoming days so make sure you keep yourself updated with all the latest react versions and update your projects [Music] accordingly now aspects of react JS there are three important aspects of reactjs we will talk about first is the virtual domor second is the data binding and third is the server s side rendering but before that if I talk about the architecture of a reactjs application any reactjs application is composed of a set of components so it includes n number of components and the inputs to these components are the properties which are referred to as props and estate and this complete architecture of components props and estate we will be talking about in the later slides so let’s talk about what are the different aspects of react chairs now there are few things you should know in advance before you start playing around with react so if you have never used JavaScript or the Dom at all before for example so I will suggest that please get familiar with those Concepts before trying to tackle or play around with reactjs so if I say what are the prerequisites to play around with reactjs so you should have familiarity with HTML and CSS you should have basic knowledge of JavaScript and programming you should have basic understanding of Dom Dom stands for document object model then you should have familiarity with es6 standards which we talked about so you have to know ESX syntax semantics and features and then finally you have to know what is nodejs and how npm is installed globally so these are some of the prerequisites I talked about to start with reactjs so let’s talk about virtual Dom now this is the first aspect we want to know about reactjs so let’s talk about the problem first what is the problem so Dam manipulation is the heart of modern interactive app but unfortunately it is also a lot slower than most JavaScript operation so when you write in JavaScript document. getet element by ID this is the ID of the element do inner HTML equal to some value now what happens actually behind the scenes what happens is that browser need to pass this HTML it removes the child element updates the Dom value with the new value then there is a complete recalculation of the CSS for the parent and child for the complete tree and then the layout gets updated so that is each element exact coordinate on the screen and then finally there is a complete traversal of the tree or the render tree and then it gets displayed on the browser now what happens as you can see on the point number four this is very much heavy that is recalculating of the CSS and change layouts because they uses a complex algorithm they affect and finally they affect the performance of the application and as well as updating the Dom properties it’s very complex now here we are talking about only one range now let’s say suppose if you want to update the Dom document object model 10 times directly then all the above six steps which I have talked about they will run one by one and they will update the Dom algorithms which will take whole lot of time to update all the Dom values that is why we say that real Dom is always lower than the virtual Dom please remember virtual Dom is a aspect or you can say concept which is introduced by reactjs now this slowness of the application can be made worse by the fact that most JavaScript Frameworks update the Dom much more than they have to for example let’s say that you have a list that contains 10 items for example so you check off the first item now most of the JavaScript framework would rebuild the entire list that is the complete 10 list that’s 10 times more work than necessary so only one item is changed but the remaining nine gets rebuilt again and again exactly how they were before so rebuilding a list is no big deal to a web browser but modern websites can use huge amount of Dom manipulation inefficient updating has become now a serious problem so what happens when you try to update the Dom in react the reconation process so what happens is that the entire virtual Dom gets updated the virtual Dom gets compared to what it looked like before and now you have updated it so react figures out the difference or which objects have changed only those change objects get updated on the real Dom and then the changes on the real Dom they cause the screen to change so I can say that in react for every Dom object there is a corresponding virtual Dom object so like any actual Dom virtual Dom you can say it’s a note tree that lists the elements and their attributes and content as objects and their property to directly change what is there on the screen manipulating the Dom is a slow process but manipulating the virtual domor is a very fast process or you can say it’s much faster because nothing gets drawn on screen it’s just like a manipulating the virtual domor as editing a blueprint as opposed to moving the rooms in an actual house if you can see that on the screen in the given tree the red one are the ones which have been changed and they have only been patched to the real domor instead of the complete tree so that is the power of a real Dom you can say now the important thing that how does react uses virtual Dom it’s very important so as I said that in react every UI piece is a component and each component has a state so react follows the observable pattern and listens for State changes and whenever there is a change it has been updated in the virtual Dom which gets reflected to the real Dom so in summary what I can say that what happens when you try to update the Dom in react so what happens that the complete virtual Dom gets updated the virtual Dom gets compared to what it looked like before you updated it and then it reflects the changes on the real domor which causes the screen to change that is the concept of a virtual domor now let’s talk about another aspect of reactjs which is data binding so reactjs follows very important to learn that reactjs follows unidirectional flow of data or one-way data binding as comp comp to other Frameworks which supports two-way data binding so in reactjs throughout the application the data flows in a single Direction which gives us a better control over the application so as you can see here that data flows from view to action from action it flows to dispatcher on dispatcher multiple actions can work and from dispatcher it goes to a store so react apps are organized as a series of nested components these components are functional in nature that is they receive information through arguments now if I talk about this oneway data binding or unidirectional data flow so flux I want to talk about little bit about here that flux is a new kind of architecture that Facebook uses when it works with react flux is more of a pattern than a framework and it has four main components you can see on the screen the one component is dispatcher now what dispatcher is doing that it receiving the actions and and it broadcast its payloads to the registered callbacks or to the store the second one is the store so a store is acting like a container for application State and Logic the real work in the application is done in the store the store you can say is registered to listen into the actions of the dispatcher and it will work accordingly and it will update the view so if I talk about view or more specifically the controller views so react comp components they grab the state from the store they grab the state from the store and then they pass it to pass it down to the child components so that is how data binding Works in reactjs it’s a oneway data binding or you can say unidirectional data flow now another concept of reactjs that is server side rendering so let’s talk about server side rendering now so server side rendering allows you to pre-render the initial state of your react components at the server side only so server side rendering which is also called as SSR in abbreviated form it is called SSR it is the you can say ability of a JavaScript application to render on the server rather than on the browser this is the exact definition of server side rendering I repeat this definition serers side rendering is the ability of a JavaScript application to render on the server rather than in the browser now there could be a question in your mind that why would you be ever want to do so so now I will list down some of the advantages that why you want to do so because it allows your site to have a faster page load time which is the key to a good user experience it helps in the SEO that is search engine optimization because what will happen that without server site rendering all your server ships is an HTML page with no body so just some script tags that are then used by the browser to render the application so in nutshell what is the difference between client side rendering and server side rendering so in client side rendering your browser downloads a minimal HTML page it renders the JavaScript and fills the content into it this is client side rendering and what is server side rendering on the other hand serers side rendering it renders the react components on the server and what is the output the output is the HTML content so that is the use of server side rendering so we talked about three important aspects of reactjs that is virtual Dom data binding and server side rendering now let’s talk about virtual Dom in detail so if I talk about virtual Dom as you can see on the screen that model gives data to view which in turn creates a Dom for it so here a model so model had information for the user ID and location it has been given this data has been given to the view which in turn has created the Dom the model gives data to the view which in turns create the Dom but you can see over here that if I change the user if I change the user from Len to Max that is the only change which has happened in terms of three properties as compared to three property only one property has been changed and that property only be reflected on the real domor that is the power of a virtual dor so as I talked about that what is a virtual domor right so virtual dor only give updates to the real Dom it not only gives the updates so that the complete page or the complete HTML or css does not get loaded again and again on the screen so now here see if location is changed if location is changed okay if I talk about the previous location the previous location was us it was compared and then you can see in the real Dom the location is changed to UK because virtual Dom it has not put heavy load on The View and makes our processing also very much faster so with reactjs when model gives data to the view if the Dom is empty react will create a Dom for it that is also a beauty or you can say advantage of a virtual Dom now as you can see here that with reactjs when model has given the data to The View and if the Dom is empty react will create a Dom for it but at the same time it is checking with the previous values and if it has found previous value is Ln and the new value is Max the user property has been changed to Max in the real term so let’s talk about the advantages of reactjs now what are the various advantages of reactjs the first one application performance is increased so which means that the creating the dynamic web applications now it has become very easier and reactjs is very much easier to learn now how the application performance is increased we have already talked about that it uses a concept called virtual Dom so enhancement of performance has been done or you can say application performance is increased because of the concept of virtual Dom it is used on the client side as well as on the server side reactjs can be used both on client side and server side and it also known to be a SEO friendly you can say library readability is improved this is one of the greatest advantage of reactj is that the readability of the code or the readability of the application has been improved a lot another is that it can be easily integrated or used with other Frameworks like angularjs or meteor or VI JS even with knockoutjs or emberjs another advantages of reactjs I want to talk about here is that the reusable components so reactjs focuses on the concept of reusability so react UI as we know that it is declared inside the components so if I talk about a component here at this stage so component is like a function that accepts the props as inputs and outputs the declared interface the U should be composed of as many as components as possible to maximize the reusability so the concept says that you should decompose into multiple components your reactjs application at the same time reactjs is a very much famous Library so there are very much great developer tools available out there for you can say Chrome and Firefox there are browser extensions for react available in Chrome and Firefox browsers so these extensions you can say allows you to inspect the react component hierarchies in the virtual Dom so you can select individual components and examine and edit their current properties and state so these are some of the advantages of reactjs reactjs is very much popular nowadays and is used by almost all the developers across the globe now applications of reactjs so there are uh these famous applications which are using reactjs in their uh application or maybe browser application and some are using in their mobile apps so some are also using react native instead of react along with the reactjs in fact so some of the famous applications one of them is obviously Facebook Yahoo Uber Netflix Twitter Instagram Dropbox and New York Times so these are some of the very big or famous applications which are using reactjs or react native in their website or in their mobile mile [Music] apps so first of all we have the jsx so we have under jsx now there are multiple components under rat that makes the entire infrastructure as flexible as possible so like we have jsx then we have riat components then we have props then we have States life cycle events references key and then we have available rout so the are multiple references that we have that we are going to discuss now the core important component first of all is components so let’s discuss on the component on the structure for components first so components are what if you have web page so if you want to update different content if you want to handle different content you can say section separately then instead of refreshing the entire page what we can do we can declare we can add different sections at as different components so that we can Define different Logic for different sections we can have different separate views and then we can render multiple components in the same page where it can all have their own separate Behavior defined right so first of all we have components so components as we discussed in application can be modeled as a set of independent components and different components are used to serve different purposes this enables us to keep a logic and view separate so react renders multiple components simultaneously and components can be either stateful or it can be stateless so before we start creating components we need to include a few import statements so we have to define the import Rea and then only we can import start importing the components and then we can Define the individual functionality for these different components one by one for example here we have this one declared as component we can have the left side bar declared as a component and so on so everything in reat is a component and each component returns a Dom object it spills the entire UI into independent reusable pieces each independent piece is processed separately and it can refer other components in output and it can be further split into smaller components so valid re component accepts a single props object argument to produce a react element and these are called functional as they literally are JavaScript functions so here we can define a button where we can define a prop as on click and then we can link this to any of the other components suppose if this if you talk about the simplest way of defining a component is through JavaScript where we can Define function and then we can Define the entire components and components can Rea can be in two different forms it can be stateful or it can be stateless it can be stateful or it can be States now stateful remembers everything again we can it has its own memory where State doesn’t remember anything it does so as soon as the entire statements are executed it simply clears out this entire memory so core which stores information about components in memory and it can change change States it contains knowledge of past current and possible future State changes it receives information from the stateless components if State change is required it calculates States internal we can say internal state of components and it never changes the state contains no knowledge of past current and possible future State changes and it provides a referential transparency that is for some for same input it will produce same output as well as a part of stateless components then we have props so Props are read only components so whether components are declared as functions or class it must never change a change its props such components are called Pure functions so all component must act like pure functions with respect to the props as what we are going to Define all right now for example let’s say if we want to create any component here we want to define the props as well then we can create a components and then we can create separate props for example if you want to create a component in react then here it’s always advisable to go to source and under Source we can create a separate folder so here we can find folder name as components and then under components we can create the component file for example here we can create a component file as suppose C mp1 suppose here we have suppose header header. JS so if we have one component defined as header. JS we can Define header. JS and first of all we have to when we creating component we can import the react Dom element we we can Define react Tom from react Dom element that we have to that from in which this is currently present so we can Define react Tom then we can declare a simple constant where we can Define con con Conant such as my component we can write any component here suppose here we can Define my component now here we can make use of a simple Lambda function now in here we can create a function we where we can Define okay we want to return and then what exactly we are looking to return here we can Define that those parameters let’s suppose here we want to return as simple S2 as we have I can say component example we can define a simple component example here we can close the H2 element and then we can now once once we have closed it we can close the statements that we have currently opened up and then we can use react dom. render so that this particular my component that we have created this can be rendered this entire component can be rendered here and then we can Define okay in which so here we are going to use document get element by ID and suppose here we want to render this where we want render this in the root ID that we Define in index oral so in in ID we have defined as root let’s change the same thing under index as well so here we can Define this to be root right so here we Define the entire root element here and then once we add we can close IND statements so we can save this and now if you want to include this back in our own statement then we can easily do that right so here we can simply Define our own application we can Define the own index whever and however we want this to be vendored and then for creating a props so Props as we know all that in simple am terms if you say props is basically a shorthand for the properties so react uses props to pass attributes from parent components to child components and props are the argument based to the function or component which is ultimately processed by react so here we can Define multiple properties for it and then we can have it rended depending upon what kind of property we are going to create here so for example here instead of using the return statement here let’s do one thing let’s see here we create a simple function so here we can Define function so okay let’s return the statement here not a problem so after this we can create a simple function let’s create a function here by the name of app so here we can define a function for app and in here we can specify return now under return we can define suppose here we want to return a division and then under division for example we have multiple message that we want to save here so here we can Define message as username for example here we are going to save multiple username then here we can Define message as suppose we have John here we have again another message that means another usern that we want to Define here suppose here we have SEL and here we have another message this can be multiple components we can save suppose here we have mik this can be multiple username that we are going to Simply render here and then when we when we are rendering the element here we can Define the in function right so now instead of Define the the even earlier instead of defining the entire my component we can Define the function and under function we can create a function for message that we have specified here so here we can Define message function and under message we are going to Define this as props with the properties that we have defined all right so here we can Define the entire properties as in how or well we want to render these as a part of the props and components and then we have other properties such as we have state so States basically allow us to create components that are Dynamic and interactive so state is basically private it must not be manipulated from the outside also it is important to know when to use state so it is generally used with data that is bounded to a change for example when we click our toggle button it changes from inactive to active state that you may have noticed and state is used only when needed and we have to to make sure that it is used in render property that we have refined in in our JS otherwise it won’t include in the state and we do not use state with static components the state can be all the state can only be set inside the Constructor alog together so we can include some code Snippets into see a small example so for example we can come back to our editor so let’s say here we can create a new file all together let’s say we name it as state 1. JS now here we can import react from react and then we can also work on importing react Dom from react now basically when we are working on the elements we have to make sure that we import the elements one by one so here we have to import react re Dom now here we can start now for the State Property let’s say here we can Define class for toggle where we want this to be extended not extend react. component that we have imported or we can also or now to work on this one here we also have to import Rea component as well so here we can also import uh if you want to import component then from the same re here we can Define the component as well if we looking to import multiple things and here we can Define react and component both from from the library where we have defined it all right so here we can define a simple class as sole as re component here we can Define us Constructor where we can specify a value for Constructor and then we can Define value such as here we can define a super where we can a super object for having the value and then we can use this dot state so here we can store the state value as this do state and here we can Define is toggle here we can Define is toggle on if it is now here we can Define the property to be true then we can Define this. handle click should be set to using this pointer this handle click dot bind so here we can bind this to the this point that we have selected so as a part of the state now here we can also if you want we can bind this a state here and then we can Define multiple States as in when this when this should be on when this should be off and then we can alter M multiple states by Define the state life cycle as well one by one so we can Define if state is again one then again how we have to switch different states from one state to the other that is something that we are going to look at as soon as we proceed further with the entire module step by step then we have life cycle so Rea provides various methods which notifies when certain stage of life cycle occurs called life cycle methods so these are spatial event handlers that called at various points in components life so code can be added to them to perform various task and they are invoked in a predictable order and entire life cycle is divided into four different phases we have the initial phase where we have get default props get initial State then we have component will Mount render and component did Mount then in the updation phase here we have have should component update component will update render and component did update then in the props change phase we have components will receive props should component update component will update render and component did update and then in impound simply is going to Define component with unmount so component is going to be unmounted after a specific value based on the condition whatever we have defined and events are basically triggered at reactions to specific actions like Mouse over Mouse click key press we can set any kind of event parameters and then we can Define it easily we can do that now as soon as any event is triggered this is going to Simply trigger the vat event and event passes the event arguments to the event handler so whenever any event is specified in GSX the synthetic event is generated and this synthetic event wraps up the browser native event and I pass as argument to the event handler that’s how it is structured and then we we have references so references stand for again and references are basically used to return references to a particular element or component returned by render so when we are rendering any element here then we can use references to specify a particular element now basically this is mostly used for managing Focus text selection or media playback and then we can also be used for triggering imperative animations or we can easily use this with third party Dom libraries as well we can do that these are the main features available in Rat and again we also have the component for rat router as well so reat router is basically a powerful routing Library built on top of reat framework so it helps in adding new screens and flows to the application very quickly so it keeps the entire URL in sync with data that is being displayed on the web browsers so in router we can have an easy understanding of the application views it can restore any state and view with simple URL it handles the entire nested views and resolutions States can be restored by the user by moving backward and forward it can help us in maintain a standardized structure and behavior while navigating it to the implicit CSS transitions we can easily do [Music] that what is conditional rendering in react J okay let’s see the definition in react you can create distinct component that encapsulate Behavior you need then you can render only some of them depending on the state of your application so when you are building some react applications we might often need to show or hide some HTML on some certain conditions right so in simple words what is conditional rendering conditional rendering is nothing but if a given statement is true then the if statement executes or else the L statement will execute so we have an example here for a better clarification now let’s imagine a person is appearing for an exam and the candidate must score 50% so this is the condition here so if the candidate scores 50% then only he will pass this exam or else he will fail so this might be considered as a simple real life conditionally rendering statement or an IFL statement and also I have an interesting fact here conditional rendering in react works the same way the conditions Works in JavaScript okay next we have different methods in rendering so let’s see what are all they first is IFL statement then element variables turn operators and finally short circuit operators let’s see each of it in a detail form here first we have IFL statement and IFL statement will execute the action contained in the if block when the condition is satisfied otherwise it will execute the actions contained in the else block so now let’s check this in a simple syntax and see here we have a condition which is to be evaluated and we have a statement inside the if block so this will execute when the condition there will satisfy or else the statement in the else block will be executed now let’s see this in a practical way now I am using visual studio code as a code editor okay now you can see I have have a user.js file opened here and we have app.js here I have included user here and also imported the user file here okay now let’s start coding now first and foremost we have a scenario here so let’s imagine there are two person one person from the edura team and another person is not a edura team person now now the person from edura if he sign in or if he log in to the this page and he must see a welcome page and if the non edura person signs in here he must see a please sign in page before he signs in so that is what we are going to design today with an simple IFL statement first and we will see the other conditionally rendered methods also so we will start coding here so first we will import react here I have the export default user so this helps me to import the user here so we have to Define it here for better practice now I have imported react here then I am declaring a class user extend react do component and also I am constructing a prop and I’m creating a super class and here I am giving the condition this dot St logged in false here I I’m giving false because the user will not be a member first then after he signs in he will become a member so I’m default keeping here as a false okay then I am rendering this const is logged in this state is log 10 okay here I am returning the condition and return the statement now I’m writing the else part return please sign in for happy learning in Ador yeah now here you can see as I have kept the state as false so default the react will work in local host 3000 so here you can see the output please sign in for happy learning Ura has I have kept this state as false now here I will give the styles for a visible changes you can see in the website so I am giving the Style part okay yeah this is image and I have given a simple Style part here so now if I keep the state as true then this welcome to edura page with an image should be executed so let’s see yeah you can see here welcome to edura with a Eda page image background and if I do false false then yeah you can see please sign in for happy learning in edor okay and also the thing is the IFL statement does not work inside the GSX because IFL statement is not a valid syntax inside the react JS now you might be thinking what is GSX GSX is Javascript XML it makes the code easier to write and add HTML into the react yes now let’s see what is element variables element variables are simple to approach to extract the conditional render into a function element variables are variables that holds jsx elements you can conditionally assign elements or components to these variables outside the jsx and only render the variables within jsx now we use JavaScript variables to store elements right so this will also Al help us conditionally render a entire component or only a part of component while the rest of the output does not change here so this is one of the benefit also it holds js6 element inside this so this is an advantage so let’s see the syntax here we have a variable and the same IFL statement with the variables assigned to the statements so let’s see here this variable is a memory for the values or it is the value will be stored in this variables and this is the same as the condition which is to be evaluated and we have a statement so this statement is assigned to this variable whether the condition is true then this statement will be executed to the user or else the else part will be executed to the user now we will see the Practical example in the visual studio code now you can see I’m editing in the same code I’m not changing anything here I’m just eliminating the F statement from here okay and now we have import and here we are using a variable so I’m using a variable button for that I have created a button here as a login button and a log out button here as well okay now I want to import this two buttons into my user.js file so let’s do that I will import log out button here and import login button okay now here these both are the child components of greetings so I want this greeting to be imported in user.js as well so let’s do that import greeting yeah now you can see right now I want this to be returned so I will return Dev greeting is loged in okay which is equals to okay this is the state F now we are using button right so I am declaring here the button okay now let’s write the main syntax let button then I’m writing if statement if is logged in button is equal to log out button on click so we are giving a event here that is on click this dot handle log out click okay now you might think where this handle came from I’ll explain now let’s give else part also copy pasting this but here log in okay we have here handle log out and login click so we have to give here also so we are giving this dot handle loging click is equal to this dot hand login click dot bind this okay so this is the event hand law dot bind this okay and also we have to give this state handle login this dot set state so I’m setting the state here as is logged in true okay now same thing for log out button false okay now this should work you can see a login button here which didn’t have previously for a statement and you can see the changes here now I am not a user of edura then I should get this page once I log in then I should get welcome back to edura page okay so this is what the element variable statement here I am assigning the values to this button if I click the button over there then the handle login click should give me true value and log out click should give me false value okay I hope you all understood the ifls and element variables next in our list is Turner operators let’s see the conditional tary operator is the only JavaScript operator that takes three operant this operator is frequently used as a shortcut for IFL statement okay now let’s see the syntax here we have a condition over here this is the condition is to be evaluated with a question mark So this question mark means if the condition is true or false if it is true then this statement will be executed if false then this statement will be executed so here the colon is the else part is the difference between true and false part now let’s check this also in terms of practical way this is the simple way of writing any conditional rendering here we have the same thing as the element variable here we have to just change the if and you can see here I’m giving the question mark here and I’m taking off this else I’m just assigning the column yeah with only this two changes here the code will be working I’m setting this to true for changing so you can see welcome back to eding with just three changes we are getting the same output here okay see log out so I’m getting this page if I log in I should get this page okay next we have a interesting operator that is short circuit operator short circuit evaluation is a technique used to ensure that there are no side effects during the valuation of the operant in an expression The Logical and operation helps you specify that an action should be taken only on one condition otherwise it would be ignored entirely here the approach is a specific case of this jary operator that we just learned now when we want to render something or nothing then we use short circuit operator now let us see the syntax yes this is the syntax now here the expression is first evaluated from the left hand side of the operant okay and if it is true then it is evaluated see the condition is to be evaluated and this is The Logical operator and this is the expression if the condition is true then this expression will be evaluated if the condition is false you will not get any kind of output here so this is the beauty of short circuit operator then we’ll see in the practical way here I have the same code just I have taken the buttons here I don’t want that button so here I am writing the syntax return this state logged in and and operation and I’m giving the style and welcome back to edor okay yes here we have the value as true so let’s check the output yeah welcome to edua and I will change here welcome back to Eda see we come back to Ed now if I change this to false so let’s see what see there is no output so that is what I mentioned you before if the condition is true then this output will be executed if false you will return nothing so this is the end of the conditional rendering now we will learn how to prevent component from rendering in rare case you might want a component to hide itself right even though it was rendered by another component to do this return null instead of its render output so returning null from a component renders method does not affect the firing of the component life cycle method so now I’m taking you through the online compiler I’m using GS pable this is a converter of the JavaScript now here we have a function called warning banner and we have props and I returning null here okay so we are writing a warning sign um let me change here I will write danger okay you can see the Visible Changes here itself danger okay here we have a phage extension and I’m giving this true here we have handle toggle click and I am giving has hide and show now if we click on hide so the message will be here hidden from rendering now I want to show this message then we can show here from returning null if we hide then you will not get any of the output here so this is also a kind of short circut operator and but here you will not get any of the side effects by giving the return as null now we’ll talk about components in detail so first thing first that in react everything is considered as a component so I will say in react everything is a component so on the screen you can see that there are multiple components 1 2 4 3 and five and on the web browser we need to add them just like components so they have been added just like a Widgets or sections or web parts or specifically components and all these components are integrated together in react to build one react application so in react what I can say is that components lets you split the UI into you can say independent reusable pieces of code and you can think about each piece in isolation and that is where the concept of reusability comes into picture that each component can be reusable at a later point of time but conceptually components are like JavaScript functions you can say like that they accept some arbitrary inputs so the inputs to a react component is called props and the return react elements describing what should appear on the screen we can easily update or change any of these components without disturbing the rest of the application so as you can see that if I want to update or change any of the feature of this component one I can update it without disturbing the rest of the application or you can say without disturbing the other components on my application now how components are split internally so single view of UI is divided into logical pieces so on the left you can see that it’s a single view or you can say react based application but how it is divided internally into logical pieces so the concept in of component in reactjs always says that you should have a parent component and then you can have child components or sub components and it behaves like a tree so at the top you will have parent component or you can say base component and then there will be some branches or some branches beneath it so the starting components becomes the root it’s called The Root component and the rest of all other becomes you can say the branches and the sub branches so in this diagram you can see the component one is the root of the UI tree two and three are the children of one and four and five are the Sub sub branches of the second component so that is how you can split the complete UI in reactjs components now each component returns one Dom element so as I mentioned that in every component you should have a render method and a return statement so each component in reactjs it returns one Dom element and how it is returned that there is a API called react Dom and it has a method called render so react dom. render will allows you to render the different components on your application so the jsx elements must be wrapped in an enclosing tag so always please remember that if you have to embed the jsx elements inside a return statement or a render method you have to wrap it in a enclosing tag so here I am creating a es6 standard component class component 3 so 1 2 2 4 and 53 is here which is written like this that hello world welcome to edura and react dom. render I am calling the component component one because component one is my root component and where I want to show you is the ID of that div element that is document. getet element by ID content now if I talk about props and state so react components are basically controlled either by props or you can say by state so we will talk about them now but before that what are just a summary of the components that everything in react is a component each component returns a Dom object as I mentioned that component divides your UI or splits your UI into independent reusable pieces and then each independent piece is processed separately a component can be divided into a root component and into the child components and then we can further split into smaller components compon now this is very important to understand that how you render a component so when react sees an element representing a user defined component it passes the GSS attributes to this component as a single object and those are called specifically props so you see here this is a function welcome which is just like a component having some props as a parameter so we call here react. render with the welcome name welcome name let’s say name is the prop over here having the value with and react calls this welcome component with the name vipul as the prop so this becomes name equal to vipul is the props welcome is a component which returns H1 tag and then react Dom efficiently updates the Dom to match this H1 tag that is how a component is rendered in reactjs now the other fundamental the most again a very important you can say fundamental of reactjs are the props now what are props so prop helps components to converse with each other or to communicate with each other this is I can compare it with you can say arguments or parameters of a function so if in this example class body extends react. component return header and footer now in header name equal to Bob and name equal to Alex so how can I return this property to this class component by using this do props do name so what this doprs do will return this doprs do name then it comes to header it will return Bob and this. props do name for the footer component it will return me Alex so how you can access props in reactjs if you want to access props in reactjs the syntax is this doprs do name so using props we can configure the components so now I have another header and footer components and I’m passing a different value name equal to Miller and name equal to CI so in the header component if I write this this doprs do name in the previous example also I wrote this doprs do name but the value was something different and in this case the footer component will return me this doprs do the value will be Cod so Props are basically used with components they revolve around the components they help in the conversation of different components via props we can do the conversation or communication between the different components in reactjs and how to access those props the props are accessed using this doprs do name or you can say this doprs do the attribute name or attribute value so if I talk about props they work similar to HTML attributes data flows from downwards from the parent component so as we are talking about a UI tree a parent child relationship so in terms of props it’s a unidirectional flow of data props are immutable that is they are pure here we are talking about pure functions or pure components so Props are immutable so as compared to which is mutable which we’ll talk later but props please remember are immutable so they are pure in nature they can set default props so we can set some default properties around the props now let’s talk about what is pure and impure here we are talking about so whether you declare a component as a function or a class so as we talked about components can be of two types a function component or a class component but it must never modify its own props so Props are always read only they are immutable in nature so it is very well said that all react component must act like pure function with respect to their props so let’s talk about what is this pure function and what is this impure function here we are talking about so for example there is a function called sum having parameters A and B and it is returning a plus b so in this particular example this is called a pure function why they are called Pure because they are not attempting to change the input values they will always return the same result for the same input so by that what I mean is that I’m not altering the value of a or b inside the function definition that’s why this is called a pure function but when I talk about a impure function because the function is impure so it changes its own input so for this particular function the input was account and amount and you can see there that I’m changing the value of account so it becomes a impure function and that is not allowed when it comes to components and props because all react component must act like pure function so Props are read only or you can say props are immutable in nature now components and props we talked about that there are two types of components you can create in reactjs because components allow you to split the UI into independent reusable pieces and you can think about each piece in isolation they are basically just like JavaScript functions but there are two types of components which you can create based on es5 or es6 is standard so if it comes to es5 is standard you can create a functional components but the recommended way and I will recommend that you always create a class component so how you will create a function component normally just like we create a function so function welcome having some props or the parameters but if you want to create a class component so you have to use the keyword class the component name which extends from react. component and it should have always have a render method and a return statement so that is the these two are the different types of components which we can create but from a react point of view they are always equivalent these two forms of component are always equivalent now another fundamental is state but before moving to the state or you can say another fundamental let’s get deep dive into some of the examples so that the three basic fundamentals which we talked about jsx components and props you can have better understanding about these okay so let’s get started so I’m just opening the nodejs command prompt so I have opened the prompt so I’m moving to the D drive and I’m moving to a specified location and then I’m am opening the code in a editor called Visual Studio code so let’s talk about the basic example that how you can render the jsx in react JS a very basic and simple example we will talk about that how you can render jsx in reactjs okay so what we have done over here is that we have a react Library the reference of a react Library okay and then reference of a react dom. library and then reference of The BJs in the script tag I have called reactdom do render and in that react dom. render because we want to render the jsx okay and please remember that you have to use script type equal to text Babel to indicate the jsx code in JavaScript of jQuery we refer script type equal to text/javascript but when we are working with jsx you have to use script type equal to text /b to indicate the jsx code and include b. min.js this is very important and this b. min.js this is a browser script tag in react dom. render in the H1 tag so please please remember that this render method takes two parameters always the first is your jsx element and another is your placeholder okay let’s move to the another demo where we will see that how we can use the JavaScript in jsx so as we know that we can also use JavaScript in jsx it takes the angle brackets as the beginning of the HTML syntax and cly Brees as the beginning of the JavaScript syntax okay so here you can see that I have created an array name equal to some names and in the react dom. render I using a JavaScript names on the names array I using the map method which is calling on the name and on the index key that is a key value payer and in this I’m returning the key equal to index hello and the name now you see here this name is represented in the cly bra as a attribute because names if I don’t put it in the C braces will be considered as a simple text so let me save this file and run this so you see here hello Lis hello Emil and hello Kate the reason being why this output because I have written here is hello and passing the parameter as a jsx so I’m using the JavaScript in the jsx and looping around the values in an array using the map function or map method which is inbuilt method of the array collection so that is why this particular output is shown hello Ellis hello Emil and hello Kate because these are the three values which are there in my array okay now let’s move to another example again a very simple one that I have created an array having the key values as 1 and two now in the react dom. render I am calling this array now what will happen that in my output it will represent that hello world react is awesome now in the next in this example what I’m doing is I’m I am defining a component so we talked about props we talked about jsx we talked about components right so in this particular example I’m defining a component so what is a Syntax for defining the component class then the component name which extends from react. component then it creates a component class and it implements a render method please remember that the class components or the function components always should have a render method class components always implements a render method to return a component instance of the class so if I talk about before version 16 of react chairs it uses react. create class to create a component class now it has been deprecated and we are using the es6 standard okay now components can have attribute and you can use this. props do some attribute to access them just like in this case I’m using this doprs do name so what what I’m doing is that in react dom. render as I mentioned you have to call the parent component or you can have to call the root element in this case there is a component called Hello message okay now in the Hello message component I am passing a prop with the attribute name let’s say equal to name and its value is John now what will happen in the Hello message it is returning hello this doprs do name as I mentioned while talking about the props that how you can access the prop okay how you can access the prop so how you can access the prop you can access the prop is this doprs do attribute name please remember how you can access it this do props do attribute name this is very important to understand and now let’s see the output of this I’m opening it in the browser it is showing me the output hello John okay now let’s talk about this doprs doch now what is the use of this doprs doch so react uses this doprs doch to access component children notes or you can say child notes so you can see here this doprs doch so please remember that the value of this. props doch it could have three possibilities in fact so if the component has no note then the value will be undefined then the second possibility could be that if can it can have a single child node let’s say an object and if multiple General nodes then it will become an array I repeat that there are three possibilities while using this doprs doch so component can have no children node then the value will be undefined in that case if it has single children node then it will be an object and if it has multiple children nodes then it will be an array so react gives us the utility called react. this is react. this is a utility given by by react for dealing with this doprs doch data structure so we could have used react. children. map to iterate into the childrens of the component without worrying its data type being undefined or object so what I’m doing over here is that I’ve created a notes list component that is a class component so class notes list extends react. component it implements a render method and it Returns the instance of this particular class since we are accessing the children of the particular component so we can use react. children. map in this I’m calling this. crops. children and it could have three possibilities but in this case since we have a children so our output would be hello world in this case the output will be hello world in a li structure so that is how you can use or you can access the children components also of a particular component let’s move to another example so types components can have specific attributes which are called props in react and can be of

    any types it can be of any type so here you can say prop types. string. is required so what happens is that sometimes you need a way to validate the props so you don’t want users to have the freedom to input anything into your component so react has a solution for it and it is called prop type so what we are doing is that we are saying that prop types is of type string and it is required this is kind of a validation we are doing so what is done in this particular example is that the my title my title is a component has a props of title prop type tells react that the title is required it is required and its value should be of type string now if we give let’s say for example title a number value so where data equal to let’s say 1 2 3 for example okay then it will result in an error which means the props does not pass the validation and the console will show you an error message something like let’s say failed prop type so what I’m doing over here is my title I’m calling the component and there is a title where I’m passing the data and data is 1 to three okay so that is how you can Implement some kind of validations or you can apply some kind of rules where you don’t want to give the user a freedom to write anything in your component so the these are some of the basic examples we talked about for jsx for props and for components now let’s move to another set of examples so let me close this very quickly okay so these are again some of the small examples which allows you to work with jsx props and components but before starting this let me tell you one thing very quickly that as I told you that this is the nodejs website from where you can install the latest node.js version and once you install so there is a GitHub project provided by Microsoft open source project which is called create react tab so you have to write the command like this npm create npm install create react Tab and once you press the enter so a project will be created for you a complete react based project will be created for you which will allow you to have the complete solution structure in terms of index.js index.css app.js and app.css so you will have a SRC folder and a public folder so these two folders are very important and we will talk about this in detail so what happens once you create a Project based on create react App application a solution a builted solution is given to you which allows you to write the code or to test your different functionalities so it has two folders one is the public folder where we have a one HTML file called index.html where we have defined a root element in a div with the ID as root if I go to the source folder the starting file is the index.js in the index.js we have react. render now as you can see at the top that we have imported react we have imported react Dom imported the index from the solution structure now react dom. render calls the parent component which is the app app is the name of my parent component so if I go to app.js there is a parent component class app extends component you can either write component or you can also write react. component that’s not a problem at all every component as I mentioned should Implement a render method and there is a return statement which Returns the instance of that particular class now I can write the jsx inside the component in the return statement simple HTML and the JS structure the div I have given the div class name equal to app now there is a header in this header I have implemented a image with a class name app logo alt equal to logo and H1 equal to class name app title now this header tag is closed here now you see the important thing over here in the main component as I said that the basic principle of reactjs that you have to compose your or decompose your complete application into multiple subc components so at the top there will be a parent component and there will be sub branches or branches of that particular component so the first component the parent component is app inside it I have called three different components one is the demo class another is author and another is CMP style so first this demo class subcomponent will be called with this this subcomponent a prop is defined a prop or you can say parameter is defined with the value react classes the value of this particular you can say prop it will be used in the definition of the demo class component so if I go to the demo class since it’s a class component it should Implement a render method and a return statement so how you can use the props you can use the props by using this do props so that is how it is used over here this do props and what is the attribute name the attribute name is the demo class the second subcomponent which is called is the author now author again has a attribute called author name which is used in this component class author extends component render implementation and then a return statement this. props do author name which means that whatever attribute to Define over here can be used in the component by using the syntax this doprs do attribute name now the third component is a little bit different the attribute name is a student name but here what I’ve have done is that in the render method I have applied a custom CSS just to show you that how you can use the attributes within the jsx in a cly bracket so where my style some styling has been given and in the return statement style equal to my style now this my style is put in a cly bracket which becomes a jsx statement after that I have done some calculations you can see here calculation 4 – 2 equal to it is in bracket then only this value will be shown okay now to run this create react application if I go to package.json file so what is package.json so package.json you can say is the introduction of any react based application or you can say the basic information of that react based application so it gives me about the name about the version about the private dependencies and the scripts so there are some default scripts at the same time you can create some custom script of yours so there is a script called start so if I have to run this complete project or application how I have to write it so in the nodejs command prompt I have to write npm start so I have clicked enter and this will open the browser on the local host on the port number 3,000 so now you can see here the output that there was a header in the header there was a image a text and this is react classes by wej and you can see the calculation has been done because we place the attribute the complete jsx or you can say JavaScript expression in the cly bracket so this is the output of this particular code which I showed you in app.js now the beauty of this particular application is that whenever you will change the code whenever you make some changes you don’t have to run the npm start again and again the changes will be reflected on the browser instantaneously so you can say that this particular application is very much reactive in nature so whenever you change the code or update any code it will directly get reflected on the browser okay so let’s go to index.js and start making some changes in the code so I’ll start with again basic jsx elements so that you can understand how we can write jsx this is a very simple example again react dom. render H1 hello world so if I go on the screen I have not saved it if I save this file and if I go to the screen it shows me hello world I have not refreshed the screen it’s very much reactive in nature okay now let’s talk about some more examples we’ll quickly see some more examples jsx I’m just showing you as of now jsx props and components examples once this will be completed then we will talk talk about State life cycle events and the remaining concepts of reactjs so in this particular example how you can add your jsx in the previous example if you have seen that in the react dom. render I have added the complete element as the first argument for react dom. render but there is one more practice which you can follow that instead of writing the complete jsx or HTML expression in the react dom. render first parameter what you can do is that you can create a element outside the reactdom do render and then pass that element in the react dom. render method so what I’ve done is that I’ve created a dummy text and created a const element in that I have created a div structure in that div structure what I’m doing is that I’m creating a button class name equal to button the text is button and then a sample text will be displayed once this constant element or you can say AJ expression is created I can pass this to react. render like this so let’s save this file and see the output you can see the output that there is a button and some sample text shown on the screen so this is the best practice you can say to write the jsx expressions or jsx elements because your jsx elements can go bigger and bigger if it is a single line jsx expression or jsx statement you can very well write it in react. render but if it is very big or going to become very very big then you can put it outside react dom. render in a constant element and then you can pass the react dom. render that element just like shown on the screen now we will see the example how you can render the elements using jsx now how you can render the elements using jsx now in this particular example please remember that every react application it should start from react. render so how the data flow goes It goes from react dom. render so first we will see what is passed over here the element which is passed is const element now in this const element what we are passing is in H1 hello format name and we have passed props as user now what is format name you can see that format name is used as a function component the parameter passed is user and for this user the properties using the arrow function here the arrow function is used the properties for this user user. first name and user. last name is used as in the arrow function which are passed to this particular function as the properties so return user. first name and return user. last name and in the react dom. render I’m calling this element so let’s save this file and what output it will give me it will give me the hello user hello format name format name is calling a user so user is whle Jen so hello vle Jen because whle is the first name and Jen is the last name so let’s close this quickly now let’s talk about some other example that how you can render the elements in reactjs now we’ll start with reactdom do render in reactdom do render there is a parent component which is clock now what is happening in this clock is that this clock is declared as you can say class component so class clock extends react. component a Constructor a super is defined and we are setting the state this do state please remember state is always set the initial state is always set by using this do state and in this do state we are passing date as a new date in the component did Mount and component will Mount we’ll talk about this later because these are life cycle methods in this just we are calling different different methods and we are setting the state in the tick method tick function we are setting this with the date new now what will happen that in the render method there is a H1 hello whle and in the H2 how we set the state please remember that we set the props using this. props do attribute attribute name and this likewise we set the state this. state. attribute so here what I’m doing this do set state. date. to local string which will show me the current date or time so hello whle it is 10:36 p.m. that is how we can set the initial State and final state in reactjs now components and props now let’s talk about what are the components and props so we already saw that in react n. render we can pass the element but in the element again instead of passing the complete jsx statement we can pass it as a component so you can see over here const element in the previous example I showed you that in the element there was a jsx expression having some div some P tag some H1 tag but in this particular example I’m passing a component to the constant element the component name is welcome having some attribute called last name now in the definition of this particular component which is function welcome I’m returning H1 hello props do last name now what is last name gen so let’s save this and let’s check the output you can see here hello last name this is my last name that is how you can render the components and props in reactjs it’s very simple very straight forward in nature now this is just an interesting one having some null value so how you can conditionally render a react component this is very important to understand that in element I have a component called message having attribute message having the value as null now in the react. render I’m passing this element and calling the message component so let’s save this file and see the output so there is no output you can see on the screen because I’m passing a null value so you can also conditionally render a react component so let’s move to another example that how you can style the react component very very important to understand that how you can do The Styling in the react component because please remember just like in Native JavaScript and jQuery we ed class class equal to some name to let’s say style any tag or component in JavaScript of jQuery but in react we use the class name this is a keyword so instead of class class we use class name so this class name I have defined in index.css so if I save this and see so you see here this is the CSS which is defined and the text rendered is Whipple box because the text is given over here is Whipple boox so this is a box small you can say a class which is defined so if I go to in index.css this is the Box small class which is defined so defining the class in CSS it’s pretty same by the dot by the dot operator you have to define the class but for calling that class instead of class keyword you have to use the class name keyword this is very very important to understand in reactjs now I will show you a very good example of reactjs that how you can Implement a multiple choice question kind of functionality in reactjs very important to understand so let me close this so for stopping this npm start you can press contrl C on your keyboard it will ask that you want to terminate the bad job you can press yes and then press enter I’m just opening another example let’s close everything just open this in Visual Studio code a very good example we will see that again the same example uh index.js I have app.js defined and index.js in index.js I’m calling react. render in this the parent component will be called the parent component is app and here in app.js this parent component is written as a function component you can see here that it is written as a function component right so let’s run this code first of all to see it running so for running any react base create create react App application you have to use the command npm start so I have just entered the command npm start and pressed enter so it will open up in the browser so meanwhile we will see the code what is written in this function component in app.js so in index.js I have written react. render this is the parent component and document. getet element by ID where I want to display or render the output okay so let’s go to app.js so in this app.js since this is a function component I have a return statement over here in this return statement I have written some basic HTML so header tag is there so in this header tag what I’ve have done is that specified the class name because you have to specify it with the class name some image will be there and then in the anchor tag I have returned some static text so it’s running as of now it’s starting the server npm server no problem we’ll move to the code again okay now in this particular example what I want to show you is a multiple choice kind of functionality multiple choice question quiz you can say so let me just do the uncommenting and let me comment this react dom. render else there will be multiple reang dom. render I don’t want that okay so so this is the application which we want to create now the question here is that how we can create this type of application now this is a multiple choice question application which is created in reactjs now as you can see this is the output which I’m showing you now as you can see on the screen that there is a section called correct and incorrect so this is my score area you can say that this is called a score area below is is my question area now these are the two high level areas or components I have talked about but at the same time I can split this complete UI into sub components so when I say this is the score area okay or let’s say the outer complete boundary is the quiz then I have a score area in this score area I have two subcomponents the correct answer and the incorrect answer and in the question area I can have two subcomponents the question and the choices so if you see it it ask me that what is 8 into 1 if I click on 8 see the answers goes is correct and the state is changed to correct equal to 1 right so I just want to show you in this particular example that how you can decompose your UI or decompose your react application into subcomponents or you can say you can create a parent child kind of hierarchy although some advanced concepts are used to build this particular application which I’m not going to tell you as of now but I just want to show you that how you can decompose an application if it is given as a requirement or problem to you then how you can decompose it into different components so let’s go back to the code and let’s directly go to react. render now in this react. render the first component or you can say the root or the parent component which is called is the quiz component now let’s go to the quiz component where is the quiz component so this is the quiz component now this is a class-based quiz component following the es6 standard class quiz extends react. component having a Constructor super and a data set is defined with the correct answer now once this data set is defined okay now we are setting the state initial state that is this dot State and binding some click events or you can say functions to it but the most important part is the render method or which implements this component implements a render method so in this render method method in the return statement I have two subcomponents which I was telling you about that this particular quiz can be divided into sub components two subcomponents one is the quiz area and another is the score area so you can see here one is the score area which will have the correct answers and the incorrect answers and another is the quiz area now if I go to let’s say the score area score area component so if I go to let me show you the score area component this is the score area component as I told you that this again score area component can be divided into two subcomponents one is for the correct answers and one is for the incorrect answers so you can see over here that there are two other sub components total correct and total incorrect right so these are the two subc components which are called in the score area component at the top now if I show you the other one which is the question area so in the main one we have the quiz area in the quiz area I can have two subcomponents one is the question and one is the answer list so you can see this is my question and this is the complete answer list so if I say this question and if I click on let’s say wrong answer so it becomes a incorrect answer right so that is how you can divide a react application or decompose a react applications into components or subcomponents so in this particular example let me repeat one again very quickly that this particular application divided into two main components that is the question and the score area again the score area is divided into the correct answer and the incorrect answer those can be considered as two subcomponents of the score area component and then this quiz area is divided into the question and the answer list so you can see over here that this quiz area is divided into question subcomponent and the answer answer list subcomponent so these are the three important aspects and then we’ll move forward to the other reactjs fundamental which starts with States okay so till now we talked about the fundamentals of reactjs wherein we talked about es5 and es6 refactoring we talked about what are the advantages of reactjs and we also talk about some of the fundamentals like jsx components and props so we talked about these in detail that what are the various types of components we can create we can create functional components and we can create class components but going forward please remember that es6 standard says that you have to create class components only because now we are going to talk about States so what are states in reactjs so just like we have props we talked about props in reactjs which is used for data management in reactjs so in addition to props react component have another way of holding the data and which is called a state so what is the state so components can change so to keep track of the various changes or the updates happening in the component over the time we use the concept of state so in this example as you can see let’s say there is ice State changes event has happened on this particular eyes and because of this change of event State changes so what is the state or the event which is changed over here let’s say we have increased the temperature and because of this increase in temperature the ice has been converted to water so what we can say is that the previous state of this particular object was ice and when some event has happened on a component which is in this case is increase in temperature the final state has become water so for State we can say that unlike props component states are mutable because in props we talked about that react props are immutable in nature which means they talk about pure functions or they talk about that you cannot change the value of the props inside a component but unlike props the component states are mutable so as I mentioned that react components have another way to hold the data and which is called State now objects which control the components rendering and behavior so states are the one which handle or control the components rendering and behavior and you can say this is the core of any react component as you can see on the screen that component is Central to any tree and around it revolves the props and the state but the important thing is that estate should be kept simple as much as possible because we know what are props how can you compare the props and state so Props are the values which is passed in by a component parent so you can see here that the props these are the value passed in by a component parent so this value is passed to another component as a prop and the value is again passed to another compon component as a prop its state is local mutable data that can be created and modified within the component this is the definition of State you can say so state is local it should be very simple in nature and mutable data which can be created and modified within the component now what is the use of having the local data or you can say local state having local data that can change within a component increases complexity and limits the composability of the component so when we talk about props we have local data which flows from one component to another component but the problem with this is that it can change within the component and can increase the complexity and also limits the composability of any component so when we talk about state in reactjs please remember that to use state in reactjs you have to use a class component there will be no more function components in our projects if you want to use a state and in the class Constructor since we are talking about class components so there will be a default Constructor over there we will initialize the component state to a sensible default value so just to repeat once again what is a state state is just another way of holding the data in reactjs now this is something very important that components in reactjs can be in two forms you can create again two types of component one is stateless component and another is State full component now what is the difference between these two state less and state full because we talked about components components can be created by two ways now when I say State less stateless means it does not remember anything it does it does not keep track of any state and what is a stateful it remembers everything it does it keeps track of every change on an event or any update in the event now let’s talk about stateless and stateful first of all what is a stateless so as we talked about stateless means it does not remember anything it does and stateful is it remembers everything it does which means if there is any change in the state it keeps track of that particular thing or particular change or particular update because of an event now stateless it calculates the state internal state of components and what is a stateful it is the core or heart of reactjs you can say which is stores the information about the component state in memory the stateless components they never change the state but stateful components as I talked about that they can change the state because there will be a initial State and there will be a final state so they can change the states the stateless components they contains no knowledge of the past so for example if there was initial state which you have set using this do state and you want to change or update that state using this do set state but stateless components they don’t contain any knowledge of the past events only the the current and possible future State changes can be tracked and stateless components when we talk about stateful they have knowledge of the past current and possible future State changes values so that’s why they are called stateful because they keep track of the previous state also stateless components you can say they provide referential transparency that is for small inputs it will produce the same output so if you give different different inputs small small inputs same inputs you can get the same output in stateful component it receives information from the stateless components if State changes required so these are some of the basic differences between a stateless and a stateful component now this is just again a summary for this stateless and stateful reactjs components so as we talked about what is a stateless so all function-based components can be considered as stateless reactjs component but here we are talking about that when we are talking about state in detail we’ll talk about State and we’ll see many examples so we will talk about only class based components and not the function based components so that’s why we are saying over here that function based components can be considered as stateless reactjs components so stateless reactjs components so which means they are pure JavaScript functions so we don’t need to have state over there in stateless reactjs components but as per the future Trend and the latest Technologies we are using stateful reactjs components which keep track of your previous state your current state and probably all the future States so all class-based components can be considered as stateful reactjs components and stateful react J components inherits from a particular class called react. component so estate also getting inherited from parent to the child so this was the brief about the state and what are the different types of component based on the stateless component and the stateful component in react JS before going to the demo I will talk about something called set state so as we are saying that there are stateful reactjs components what does it mean so you have to set your initial State and then you will set the final state so that is the you can say current state and the future state so there is a method called set State now what does it do so you can set the initial state by using this do state but if you want to set the future state or you want to update the state you have to use a method called this do set State Now set State method it merges the new state with the old state so for example your new state value is one and the previous state value was zero or maybe false and true the latest value will become the combination of the new state with the old state so all the previous state will remain unless it is overwritten so if you are not overriding or overwriting the previous state it will remain in the memory so for example consider a state object with properties A and B having values for example 1 and two so a is equal to 1 and B equal to 2 respectively now calling set State what will happen so calling set state with the property Bal 3 and C = 4 so it will produce a new object where B will become three and C is equal to 4 but the previous value of B was two so that is how the property of a remains unchanged the property B in this case is overwritten by the new state and in this object of the State Property C is newly added so in addition to changing the state of the component set State please remember set State method is very important it also causes the component to be rendered eventually and for performance reason you can say set State calls a batch method and there is no guarantee that the state can change immediately so by this we mean that there is a method called set state by which we can set the final state of any react JS component a class component now let’s move to some demo that how we can implement this kind of functionality so let’s see this so this is your index.html a simple HTML file where I am calling a script called like button.js by using the script tag and in this like button.js script I’m using the class component and the concept of state so this is my first example or you can say first demo a very simple one to uh let you understand that how we can work with reactjs State feature or you can say aspect because react thinks of a component as State machine and you can use this. state to hold the component state so let’s write this code what I want to do is that in react. render I’m calling a component let’s say called app now I will go to app.js where I would be writing this component so this is a function component I don’t want any function component anymore I’m just commenting it and I have commented this and I’m also commenting this now what I’m going to do is that I’m going to write a component with the name let’s say app how I will write it I will write class app it will extends from a parent class called react. component and in this react. component you have to specify a Constructor which will have the parameter as props and in this Constructor you have to call Super which will return again the props to the class instance and then you have to set the initial State this is very important that how you can set the initial state by using this dot State this is the initial state which I’m setting over here and this do state I’m setting is let’s say for example light is my property and initial value is false and then you have uh event for example uh this dot handle click is equal to I’m binding this event to the class this dot handle click do bind to this that’s it so we have set the initial State and what we have done is that we have binded a event handler to this particular class now we already know that every class component will have a render method so we will implement the render method over here now in this render method what I’m going to do is that I will have a return statement so before that I’m just writing a uh variable called where text where I’m checking the state so this do state do like I will check this using a tary operator if it is true then it will show me like else it will show me that I have not liked it that’s it I just created a variable and then I will have a return statement now what I’m going to to write in this return statement I’m just writing a simple jsx over here a very simple jsx I’m going to write a P tag I’m just passing this text as an attribute in the parenthesis I’m just writing a demi text now what we are going to do is that we have method handle click which we are going to Define now so handle click based on a event and in this event what I’m saying is that I’m going to set the state now so in this particular example what you have seen is that I have created a class component which extends from react. component it should have this dot State reason being I’m setting the initial state it has a onclick event you can say which is binded to this particular class then there will be a render method which is required in this render method there will be a return statement and in this return statement I am checking the on click so on click event I’m checking over here and what I will call I will call this dot my event name what is my event name handle click now on the click of the let’s say P tag what I want to call I want to call this handle click so in this handle click what I’m going to do is that I’m going to set the state because my initial state is liked equal to false now I want to set the final State now final state is set by as I mentioned this do set state now let’s define the property over here what was our property the property name is light and what I want to Define is this dot state. like value that’s it so what’s going to happen is that I have mentioned the not so it will automatically become true because initial value like value is false so this completes my code over here let me repeat once again I’m using the create react App application in this create react App application we can change maybe the component name also so this component name needs to be called in index.js and just save it so what we are doing over here is that in the react dom. render I’m calling a component this component is defined in your app.js now in this app.js what I’m doing is that this is the like button now like button is a class based component you can see here that it is defined as class now let’s define this export default like button and this is used over here in index.js like button correct now what will happen that you have set the initial State using this do state equal to like false and in the handle click whenever that P tag on click event will be called this handle click event will be called which will set the final state of this particular P tag so what we are saying is that my initial state is false and whenever a button Buton or any control will be clicked I am changing it to true so I am changing the state of that particular control now let’s see the output of this particular application what I’m going to do is that I’m opening it in the browser now you can see that this is a static text and when I’m clicking this particular uh button like it is saying me the message that you like this just like we wrote over here you like this so it is showing me the message that you like this so that is how you can set the initial State and final state of any react component now just to repeat once again that what we are saying is that for setting the initial State you have to use this dot State and for setting the final State you have to use this do set State method just as you can see on the screen okay now we are talking about State here let me tell you that state is similar to props but only thing is that it is mutable and and fully controlled by the component because what is happening that right now we are storing our all the data in an array in a variable for example but that is a good way to start with reactjs but later on if you want some more operations or more frequent flow of data in reactjs you can think of a state so you can think of a state as any data that should be saved and modified without necessarily being added to a database so you can say state is a place from where the data comes from and we should always try to make our state as simple as possible and minimize the number of stateful components so for example if we have let’s say 10 components that need data from the state so we should create one container component that will keep the state for all of them we should not create 10 components we should create one component as a parent component and then the other could be the child components okay now let’s see more examples based on the state so what I’m going to do is I will create more State examples or state demos to show you the concept of State in detail I’m going to create a class component so class app which extends from react. component I’m using a create react app getup project Facebook project you can say and in the react dom. render I have to call this app component so let’s call first this in index.js this particular component app and then in app.js what I’m going to do is that I’m going to create a class component with the name app so first thing first first we have to create the Constructor which is passing the props and then in Constructor what you are going to do you are going to set the super keyword this is the first and most important thing to do in the Constructor and then what we are going to do in the Constructor as I mentioned that the best place to set your initial state in reactjs is is the Constructor okay so I’m going to write this dot state I’m setting the initial State over here please remember that if you have to set the initial State you have to do it with this do state in this do state you can Define n number of properties any properties you want you can Define in this so let’s define over here for example two properties one property I have let’s say for example header this is just a property I can write it text for it let’s say header from State any text you can write this is just setting the initial State and then I have one more property let’s say for example content this is my second property in my initial State and any text I can write which I can write as content from state so what I have done is that I have set the initial state with the two properties header and content this we are creating a class component now every class component you already know it should Implement a method which is called render and every render statement should have a return state so I’m saying render and then I’m saying return in this return what I’m going to do is that I’m going to Define my some custom you can say jsx so let’s define in return so for example I have a Dev I want to write a Dev in this Dev I have H1 tag in this H1 tag I will Define my one property called header and and then again I have a h2 tag where I will Define another property called content so let’s save this file now how you set the state now even you can set the state in jsx so just like this if you want to set the state in jsx you have to place this cly braces and what will be the state you want to become so it should become this do state DOT value is header because header is a property which we have already defined and here I want to say this do state dot for example content in the previous example you might remember that I used this do props do attribute name similarly in state also while using the state we can use for setting the value or showing the value passing the value to the component by using this do state so here I have two properties header and content so I can use it like this. state. header and this. state. content so let see the output of this particular example for this example what we can do is that here I am defining a div and in this div what I’m doing is that I’m doing class component or you can say creating a class component and in this what we have done in index.js that in index.js I have called this component this is my component which is a class based component please remember that while using the state always you have to create a class component and and just like we use props in this doprs do attribute name the same way you can use State just like this do state do your attribute name in this case your attribute name was header and content now let’s move to another example where we can see that how you can use State and props in one single example it’s not always the case that you have to use only state it’s not necessary you can use State and props together also so we will create this example only or we can extend this example only so what we are going to do is that I have a return statement over here where I’m writing let’s say two more subcomponents what I’m going to do is that in this div I have a div over here I’m going to Define two more sub components so my parent component will be app and then I have two subcomponents for example let’s say header and the content so instead of this H1 tag and h2 tag which I have cre created what we can do what I’m saying is that when you create a parent component so parent component will remain the same that is app I can have some child components also where I can pass the attributes or the values as props which will Define that you can use props and you can use at the same time state in one example so let’s do that so what I’m going to do is that I’m going to create two sub you can say components so let’s say one name is header this this is my one of the component and this is the prop value the attribute which I can pass like this dot state do header and then I can close this component and another component I can create is let’s say component name will be content and I have a prop I can pass it as a prop and then I can write here this dot state do content what is the change we have done over here what we have done is that we have created a class component that will be the parent component in the render method in the return statement it has two child components so we have to Define these child components now so what we are going to do is that we are going to Define these two components now so let’s define these so what I’m going to write is that I’m going to write class my component subc component name is header again it will be a class component so it is going to extends from react. component and the same component I have to create for Content so this content component needs to be defined so I have two subcomponents now one subcomponent is the header which is having the prop value as this. state. header and another prop value as this.state do content so let’s define this every component should implement a method called render in render there needs to be a return statement now in this return statement just like we Define H1 tag I’m going to Define this in a Dev here so I will say Dev and then I will say H1 now in this H1 what I want to pass is although the value is coming from a state but the value which I want to pass over here is in the form of a prop so what I want is that I will say this Dot props dot in the header props what is the name of the prop it’s header header prop similarly what we are going to do is that in the content sub component again we will have a render method and then there will be a return statement in this return statement what I want is that I want to define a h2 tag let’s take it in a container that container is let’s say Dev I want to take it in container and in this H2 I want to pass the props so what is the name of the prop attribute that is content prop so what I will say this do props dot content prop okay so what we have done over here is that in the previous example if you remember that what we did was that we didn’t Define two subcomponents okay so in place of this let me copy this somewhere and then can show you so in place of this earlier what we did we didn’t Define the two subc components what we defined was a container which was a div and in this div we had one H1 tag in this H1 tag what we were defining we were directly using the state value how we were using state. header and then in a h2 tag what we were doing we were using the content value so we were saying this.state do content now let’s see the output of this particular example first what we have implemented without using the props so let’s save this file and let’s go to the browser so now what it is saying that header from State and content from State I have already run the npm start command for this create react application so you can see the output in local host on the port 3,000 header from State and content from State why this output is coming because the header value is header from State and content value is content from State this was the direct way without using the props how we have used the props by using the sub component concept so let’s implement this subc component yeah now what we are doing is that we have defined two subcomponents which is header and content these are the two subc components class based components and we have passed the value as props now you can see this. state. header header value will come and let’s say we can write some updated value new header from State and new container from state for example and you can see the value over here new header from State and new container from State this is the output basically what we have done here is that I have showed you both the ways of using the state in reactjs which means that you can use it without props and you can use it with props also so there are you can say two ways of using state in reactjs but I will prefer I will recommend that you can use state with props and if whenever required or whenever you can say apply the props Just go with it it’s not always necessary that you have to implement every time only with the state you can very well use props and state together in the same application now just a few tips of using State and reactjs just a couple of tips from my side that do not modify the state directly don’t even try to modify the state directly you always use the set State method and the only place where you can assign this do state is the Constructor these are the two main things so what I’m saying over here is that if you have to specify this do state where you can specify this do state you can specify this do state in the Constructor only this is the first you can say right way to use the state now what is the other thing that State updates may be asynchronous in nature so react May batch multiple set State calls into a single update for performance because this. props as we use here this. State and here we use this. props so this dot props and this do state may be updated sometimes asynchronously so you should not rely on their value for calculating the next state so if you want to set the value of the next state don’t rely on the value of this do props or this do state and the third thing which I want to tell you about state is that State updates are merged when you call set state so what happens is that react merges the object you provide into the current state so these are some of the tips you can say from my side for using State and reactjs so let’s come back to this PPT and let’s talk about the another aspect of reactjs which is life cycle now what is life cycle in reactjs or what is the use of adding life cycle method to a class component in reactjs react provides various methods which notifies when certain stage of life cycle occurs called life cycle methods so there are many methods in uh reactjs which notifies when any stage of a life cycle occurs now what are the different phases of that life cycle so it start with initial phase then it comes to updating phase and then props change phase and finally the unmounting phase where you can can free out some of the resources so what we are saying is that there are four phases in which you can Define the life cycle of a particular reactjs application so what happens is that it’s very important in the application with many components let’s say there are 10 components in a reactjs application it becomes very important to free up the resources taken by the components when they are destroyed so for example a component is destroyed so it becomes very crucial very important to free up the resources which are taken by that component because once it is destroyed so the resources which has it consumed should get freed so that’s why we can declare some special methods over the component itself or you can say we can decare some special methods on the component class to run some code when a component mounts or when a component Dismount so these methods are basically called the life cycle methods Let me Give an example comp component did Mount this is a life cycle method example it runs after the component output has been rendered to the Dom so let’s talk about these different different life cycle methods in detail now so the first phase in the life cycle of any reactjs application is the initial phase now what are the different methods available out here because in this phase component is about to make its way towards the DOR it has not yet reached the DOR it is just creating its way or about to make its way to the dwn this phase you can say consist of the following methods which are invoked in a predefined order so the first method is get default props get the initial State component will Mount render method we talk about and the component did Mount and as I mentioned that component did mounted method runs after the component output has been rendered to the Dom so different methods they have their different you can say usage in any life cycle of a reactjs application now if I talk about the second phase that is you can say the updating phase when it phase comes into picture so once the component is added to the D because in the previous phase that was the initial phase so we what we said that we talked about that the component is making its way or it’s on its way towards the Dom but now since it has reached the Dom it is added to the Dom they can update and render only when a state change occurs so basically in the updating phase once the component is added to the Dom they can update and rerender only when a state change occurs so this phase consist of the methods for example should component update component will update render and component did update so please remember render is a common method in almost all the phases or the life cycle of a reactjs application so we have talked about here the initial phase we have talked about the updating phase so please remember that neither parent nor the child components can know if a certain component is stateful or stateless and they should not care whether it is defined as a function or a class but the most important thing is that when we are dealing with State our component should be of a class type it should not be of a function type so that is why you can say state is often called as local or encapsulated so it is not accessible to any component other than the one that owns and sets it a component may choose to pass a state down as props to its child components just now we saw the example of the state and props now let’s talk about the third phase that is props change phase so we talked about the initial phase we talked about the updating phase now what happens that after the component has been rendered into the Dom so in the initial phase what it was doing it was making its way towards the Dom in the initial phase in the updating phase what it was doing that it has been rendered on the Dom the component has been rendered on the D now the third phase is props change phase after the component has been rendered into the Dom the only other time the component will update apart from the state change is its props value changes so please remember that through State we can change the value or through props also we can change the value just like we saw that this do props do attribute name for example this doprs do name just like that we can say that this do state. attribute value just like we saw in the previous example so what we are saying over here is that this do props do attribute name can change can make the changes in the component and this. state can also make the changes in the component now what are the various methods which get invoked in this particular phase in a predefined order component will receive props should component update component will update and component did update of course render is a common method in every phase of the life cycle of a react application last phase in the life cycle of a react application is the unmounting phase this is the last phase of the component life cycle in which the component is destroyed and removed from the Dom this is called unmounting so we were talking about the mounting and the unmounting mounting means when the component is added to the Dom and unmounting means when the component is removed completely from the Dom and this phase only consist of one method no render method over here the only method which is there in the unmounting phase of a reactjs application is component will unmount now let’s see how the life cycle goes in a reactjs application so we talked about the initial phase we talked about the updating phase we talked about the props change phase and then we talked about the unmounting phase so these are some of the methods which are mentioned over here so it started with the initial phase where we had the method called get default props then get initial state will be called component will Mount will be called and then render will be called and then component de amount will be called as I mentioned that all these methods always called are called in a predefined order so please remember that if you write a method let’s say for example get default props and component will Mount so you should understand that in which order it will be called so first of all get default props will be called and then component will Mount will be called now you can see on the screen that once this initial phase is done what we have the other phase that the props can change the state phase and then we have the update phase we are different methods could be called so what are the different methods that component will receive props should component update component will update render and component did update so these are the different methods in the update phase now if I talk about the last phase which is the unmounting phase so what happens that reactdom do unmount we call the component will unmount method for the unmounting phase for completely removing the component from the Dom that is the last phase or there is one method which is called over there which is the component will unmount once the component is completely unmounted or destroyed from the domor again the life cycle start from react dom. render and again the get default props methods is called so that is how this complete life cycle again goes on and on now this is the description of these life cycle methods which we talked about so so we talked about component will Mount component did Mount and so on so what happens with component will Mount is that it is fired once before initial rendering offers and it is a very good place to wire up your message listeners please remember that this do set state does not work here the other method in the life cycle is component did amount it is again only fired once in any reactjs application after initial rendering occurs it can use this. getd node so what is happening over here is that component will Mount will always be called before the rendering occurs and component did Mount is fired after the initial rendering workers so there is you can see very a minute difference between component will Mount and component did Mount will means uncertainty so it is going to render or the initial rendering has started but it has not been yet rendered on the Dom and component did Mount means it has rendered on the browser or on the Dom it will be fired once the initial rendering on the Dom occurs the third method is component will update it is fired after the component updates are made to the Dom you can use this.g Dom node for updates over here the other method is component did update now what happens with this method is that it invoke immediately after the component updates are flushed to the Dom so any change any update is there in the component it gets flushed to the Dom then you can call component did update and this method is not called for the initial rendering please remember this is very important that for initial rendering of the reactjs component component de update method is not used you can use this as an opportunity to operate on the Dom when the component has been updated so for example it has been updated using the props or using the state then only you can use component did update component will unmount we already talked about this that this is a single method which is called in the unmounting phase of the life cycle of a reactjs application it is fired immediately before a component is unmounted from the Dom and it’s a very good place to remove message listeners or you can say General cleanup or Garbage Collection kind of activities you can do in component unmount method another is component will receive props it is fired when a component is receiving the new props you might want to use this. set State depending on the props just like we saw that we can use both props and state in a single application the other is that should component update now this is pretty interesting that this is fired before rendering when new props or state are received received it will return false if you know an update is not needed so you can check on any of the component based on the state and the props that if any update is required or not and accordingly you can return false and true based on this method which is should component update now this is very much interesting Constructor we talked about Constructor that whenever we are using the class component in react JS you have to use the Constructor you have to pass the props and then you have to use a super keyword now what what is this Constructor in props that if you don’t initialize the state and you don’t bind the methods you don’t need to implement a Constructor for your react component and ultimately we already talked about this will be converted into function based component but here we are talking about state so our focus is for class components please remember if you are not binding anything in your component if you are not using any state then you don’t need a Constructor in your class the Constructor for a react component is called before it is mounted when implementing the Constructor for a react component subclass you should call the super keyword before any other statement because if you will not call the super what will happen that this props will become undefined in the Constructor which can lead to errors or exceptions or bugs in your application so that is why it is said that the super keyword should be called before any statement in your reactjs application so first you have to call the Constructor and then you have to call the super keyword so that this do props should not become undefined so what we are saying is that typically in react class based react component you can say Constructors are only used for two purposes specifically it is used for you can say initializing the local state or you can say initializing the initial state by assigning an object to this dot State and then what we are saying is that for binding the various events or binding the event handler methods to an instance of the class you need the Constructor please remember these are the two basic purpose of using Constructor so if you want to set the initial state that will be done in the Constructor if you want to you can say bind even Handler methods to the class instance that will be done in the Constructor of the class now this is just uh you can say pictorial representation of the different phases now if I talk about the life cycle of any react application it revolves around the three important phases mounting updating and unmounting so what we are saying that first you add the component to the Dom you do some changes or updates and then finally you unmount it so what are the different methods which are shown on the screen you can see that what are the different methods we generally use while mounting updating and unmounting so in the mounting we place the Constructor we can call the method called component did Mount and then when it comes to updating phase we can use three different types of methods new props for get derived state from props or should comp update we can use this. set State and we can use dis. force update and the different methods which we can use in the updating phases component did update and finally in the unmounting phase there is only one method which we can use which is component will unmount so this is just a representation you can say summarized way of representation of the life cycle of a react component so we talked about till here jsx we talked about components props States and life cycle now another important aspect you can say a very important fundamental of reactjs is events so what are events events are the you can say triggered reactions to specific actions so for example we can have onclick event we can have Mouse click we can have Mouse hover key press all these are called events and react CHS so for example there is an action so some action happened on the react component and then we have a react application which is called event now some event has happened on the react component and it becomes a reaction so that is a definition of events now first we talk about that how the concept of event work in other uis as compared to reactjs and then we will talk about that how events work in react GS let’s say I have a control let’s say three controls or many controls button type control now what happens that in other uis on every control you have to implement a event listener as a corresponding event handler this is very much required which decreases the performance of the application on the Dom because what is happening over here is that for different controls just like

    shown over here that you have a different controls different buttons or maybe another controls you have to implement the event listener on every control and when a event listener is implemented a corresponding event handler will be required so that is how the different uis or other uis work when it comes to events now let’s talk about events in react how react manages events in react so what happens is that if you have different controls then you will have only one event listener and one event handler attached to it so which increases ultimately the performance of reactjs application please remember that react events are named using camel casing rather than uh lower case so you have to Define events or you can handle the events with camel case only and with jsx you can pass a function as the event handler rather than a string so we will see that in the demo so before moving to reps now the other fundamental of reactjs let’s see some of the demo of handling events in reactjs so for that I’m going to show you a example we have talked about State we have talked about props and jsx and all that stuff so this is just uh you can say playground which I generally use to work with reactj which is called pen.io so in this particular example what I’ve done is that I’m using a conditional rendering based on my click or you can say based on my event so we’ll start from react doom. render so this is the react doom. render which is calling a parent component which is login control now if I go to login control which is a component now in the login control it is a class based component which is extending from react. component now every class component if it is binding something or setting the state it should have a Constructor it should have a super keyword so that this do prop should not become undefined now here you can see that I have defined two event handlers for binding in the Constructor of the class one is handle login click and handle logout click I’m binding it over there and setting the initial state that is logged in is false so initial state is is logged in is false that the user is not logged in as of now now that is why you can see that it is saying in the output that please sign up and showing me the button of login what is happening in handle login click and handle log out click we’ll see later first we will see the render render method implementation in the render method I have declared a constant is logged in equal to this do state do is logged in now what will be the value in this because it is initially set to true you can see here initially set to it is false and then in the events what I’m doing is I’m setting it true or false so first of all it will take the initial value I’m taking a let button and if is logged in if it is true then this button will be called where I’m calling a component called logout button and if it is false then I’m calling another component which is again login button if it is true then log out button if it is false it is login button now you see over here on click this is called event in react js on click is a event this event l listener is bounded to a event handler so this is binded to a event handler which is handle logout click and this is on click event is binded to a event handler which is called handle login click so we’ll see what is happening in handle login click and handle logout click in handle login click we are setting the state and we are setting it to true and in the handle log out again the user will be logged out so we are saying that is loged in is false so let’s see the implementation so what is happening that if I click on login it is showing me the message welcome back you can see on the screen so function user greeting is called welcome back and when I’m clicking on the button again log out it is saying me please sign in you can see over here please sign up so what is happening is that in the login button and log out button so I have two function components login button and log out button so what I’m doing is that I’m again calling the event that is on click equal to props do on click and in the greeting method what I’m checking is that if it is logged in then it will return another component user greeting which is again a function component and then if it is logged out then it will say guest greeting again which is a function component so that is how you can use events in reactjs now let’s see another example of using events in reactjs so what we can do is that we have to start from react. render in the react dom. render what we are doing that we are calling a component which is tole so this will become my parent component now in this strle what I’m doing is that I’m writing the Constructor that is very much required for a class component because I’m setting the state then there is a super keyword in the this. state I’m defining a property is loged down true so is toggle on is tole on property is always true and I’m binding a event this do hand click so this. handle click. bind to this particular class and in this handle click event what I’m doing is because I have used a button on the button I calling an event now what is the event onclick on click event what I’m doing this do handle click and in this what I’m saying is does this do state. Isle on what will be the text of the button so when I will click if it is true it will be on if it is false the text will be off so let’s see the output if I click on this button the text becomes off if I again click on it the text becomes on so this is just a text of the particular button which we are changing based on the state so this. state do Isle on so what we have done is that we have set the initial State first of all initial state is true so whenever it will be true this do state. is struggle on whenever it will be true the text shown is on once I click on it now the this do state. is struggle on becomes false and whenever it becomes false the text is shown as off so that is how we can work with the basic all the fundamentals we can apply in one application it’s not like that in reactjs that you have to come up with only jsx based application or component based application it’s not like that all the react fundamentals which we talked about over here should be used every time in combination then only you can learn reactjs in detail so what I’m saying is that you can apply jsx components props State and then life cycle methods and some kind of events for example onclick events just we saw all these things you can combine in one react application so let’s see more examples of events so what I’m doing here is let me remove everything from here okay so let’s create a parent component app for a very simple example of the events so what I’m writing over here is that class app extend re. component I have to define a Constructor The Constructor I have to Define props I have to use the super keyword so that this do props does not become undefined so what I want to do is that I want to set the initial state with this do state and then I want to use I can use here this Dot update State also so update state will be my Handler and I can Define the update state so what I’m doing is that this dot update state do bind and I want to bind this to this particular class uh let’s remove all this okay so let me copy this particular toggle example from here what I want to do is so in this particular index.js let me Define this toggle so what we have done is that we have defined the same component toggle over here and in this toggle what we have done is that we have implemented a Constructor as I told you okay and then in the Constructor what we have done that we have binded a event and initial value of the toggle is true and then the final value on the click of the you can say button I’m setting the state as this do set state where I’m changing the value called is stral on from True to false now let’s talk about child events what is the concept of child event in reactjs so when we need to update the state of the parent component from its child so generally what we have learned till here is that you can update the child even from the parent but there could be some situ situations when you need to update the state of the parent component from below that is from the child so we can create a event handler for example let’s say update state in the parent component and you can pass it as a prop to the child component where we can just call it so let’s do that so what I’m going to do is let’s index.js go back to index.js and let’s define a component with the name called app and in the app.js what I’m going to do is that I’m going to define a class component with the name app which extends from react. component so this is my class component which I have defined now in this I have to define the Constructor with the props and in this Constructor I have to define the super keyword so that this do props should become undefined now in this super we have to let’s say uh Define for example I have to Define initial state so what I’m going to do is that I’m going to say this do state is equal to so I have to define a property property could be let’s say data and I have to Define some data over here let’s say I say it to initial data this is my initial data so my Constructor is done now I can write here let’s say for example end of class this is just my hand of Constructor so that you can understand well now let’s bind a method to this Constructor if you want to bind a method you have to bind it inside the Constructor please remember so let’s say I want to call update State this is just a method name you can use anyone of your choice any name this dot update State how you bind it you bind it using the keyword bind and this so by this statement what you say because you have to Define this inside the Constructor by this you are binding a method which is called update State and we are defining now the update State this is a method we are defining and in this update State what we can do we can set the state now what state you have to set so you are going to set the value of let’s say data because that is the property you defined and let’s say what we want to do is the data for example updated from the child component something like that could be of any text no problem at all so this is the end of the update State method now you have to implement always a render method now once you have implemented a render method it should have a return statement so we are using a return statement over here so this is my end of render method and this is let’s say end of return statement okay now in this return what I want to do is that let’s say create a container so my container is div and in this particular thing what I want to do is I want to define a sub component because in this particular uh demo what I’m going to show you that how you can update the state of the parent component from a child component so I need to have a child component over here so I’m going to define a child component which is let’s say name is content and I’m just taking a prop value over here with the attribute my data prop and I’m saying value of the initial value of the state is this do state my attribute name is data and then what I’m seeing is another prop I’m using is update this is the another prop you can use multip M props multiple attributes and I’m saying is this do update state so what I have done is that I want to update the state of the parent component my parent component in this case is app and I want to update the state from a child component which is the content so this class is over here and then I want to define a sub component a child component because we have not defined it yet yet so I will write class content my component name child component name is content so I have to Define over here so I’m saying class content extends react. component and what I’m going to Define here is uh Implement a render method and in this render method I will have a return statement that’s it now in this return statement what I want is let’s say I have a container a div again and uh for example let’s say I want to add a button and button will have let’s say on click event and on the on click event I want to call the props so what is the props attribute I want to call this dot props dot the update State prop update State prop I want to call this button is closed and let’s say the name of the button is as of now give it click now one more HTML tag let’s add one more HTML tag to use the another prop attribute and that is this dot props do my data Pro that’s it let me tell you that what we have done in this that in reactjs when we need to update the state of the parent component from the child component so here you can see on the screen that I have created here two components one is the parent component which is the app component and another another is the child component now what happens is that what you can do is that you can update the state of a parent component from its child generally what happens in a general scenario that a parent component updates the state of a child component but in this particular example what I’m going to show you that how you can update the state of a parent component from a child component so what I have done is that I have created a event handler update state in the parent component you can see that this particular event handler this is created in the parent component but it is passed as a prop to the child component you can see over here this particular event handler is passed as a prop to the child component so let’s see the output of this I’m saving this I’m just clicking and when I clicked it the button was there in my child component you can see the state has been changed and it is saying that the data has been updated from the child component you can see over here which means that the event handler which we created in the parent component can be passed as a prop so one good learning from this particular example we can get that the event handler which you are creating can also be passed as a prop and that prop can be used in another subc component or child component now another thing which I want to tell you that how you can prevent component from rendering for example there could be cases where you don’t want to render a component or you don’t want to hide a component all these are rare cases but in rare cases you might want a component to hide itself even though it was rendered by some another component so for that what we do generally is that we return null instead of its rendered output that is the only trick by which we can prevent a component to render on the Dom that you can return null instead of its rendered output now what we will do is that we can see the component events that how events are created in components so this I have already shown you let’s go back to the slide now and let’s talk about some other fundamentals so refs now we will talk about refs what is a ref in reactjs so ref stands for references you can say ref provide a way to access Dom nodes or react elements created in the render method this is the definition of refs so what I’m saying is that ref stands for references and they are used to return the references to a particular element or you can say component returned by the render so if I have a react element having a render method I have to place some reference in my component so by using the ref keyword I can place a reference to that particular component in reactjs so what happens that in the typical react data flow props are the only way that parent component interact with their children so what we have seen is that in reactjs probably if you want to pass the data or you want to flow the data from parent to the child props are the only way to modify a child you rerender it with new props however there are few cases where you need to you can say imperatively modify a child outside of the typical data flow so the child to be modified could be an instance of the react component or it could be a Dom element so for both these cases react provides an escape hch you can say and which are called refs now the important thing is that when to use refs so there are particular cases you can say few good use cases for using refs those are you can manage the focus you can manage the text selection or you want to apply a media playback there you can apply the refs you can apply the refs in application where you triggering imperative animations or you are integrating with third party Dom libraries probably there you can use very well reps so important thing is that avoid using Reps for anything that can be done declaratively now how you create the Reps reps are created using react. Create ref method and they are attached to a react element via the ref attribute so ref is a attribute refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component so this is very much important about react ra now if I show you that how you can use the refs so let me go back to the same example now ref is used to return a reference to the element this we have already known now what are the react WS although I will recommend that refs should be avoided in most of the cases however they can be useful when we need Dome measurements or to add methods to the components so we will see now that how you can use revs in this example I’m going to show you that how you can use revs to clear the input field okay so let’s remove everything we have a Constructor props this. State let’s remove this method and let’s remove this render remve this class okay so we are using the same app component what we are going to do is that we have a Constructor with a props keyword and the super keyword with props we have the initial State called this do state having let’s say for example some blank data in this case and then you have this. update State equal to this. updat State dobine and let’s have one more you can say Handler event handler which says this do clear input equal to this do clear input. bind this this Constructor is closed over here let me save this file and then I’m going to Define this update state update State event handler we have to Define so I’m writing here update State let pass argument to it and then I’m setting the state as so this do set State what is the value of the property value of the property I have to Define over here okay the value of the property is data and in this data what I’m doing is data value should be e do Target do value so we have defined the update State also that whatever value will be the input will become the set State value now we have to Define another method that another method is clear input so let’s copy and paste over here I have to define the clear input method now in this what I’m saying is this dot again I have to set the state so I’m setting the state same value I have to use and that is data so I am making it again Plank and after that I’m finding the Dom so how you can find the Dom reactjs is react Dom dot you have a method or you can say function called find Dom node so I want to find the Dom node and how can I find the Dom node I can find it using ref so what I’m saying is this dot refs I’m just taking a input value that is my input text box which I’m going to Define in the render method what I will do that I will use the focus method for this this is my clear input function and finally we have the render method Implement for the class and in this render method you have to apply the return statement the return statement we are going to write some HTML or jsx so I’m creating first of all the container my container is div I’m taking an input type value equal to this. state. data so that will be the blank value initial value this do state. data I’m taking a event over here on change so whenever there will be a change in the text box this method or this event will be called and in this I’m calling this dot update State and I’m also defining the ref which is very important ref is which I have defined here my input so on my input the ref will work so this input is defined so this text box is defined and now I will have uh button control where on click event needs to be defined so I’m defining the onclick event the name of the button is clear so on click what I want to do is that I want to call a binded method which is this do clear input and after that simply I want to place a H4 tag in this H4 tag I will show the final State value by using this dot final value how can I show that this do state do data so this completes my explanation of the Ws where what we have done is that we have created a component called app in this particular component what we are doing is that we are setting the initial state with a blank value and I have called two event handlers you can say this do update State and this do clear input now in the update state I’m setting the value what is taken as an input from the user in a you can say text box and then in the clear input what I’m doing is that whenever this clear input will be called I’m setting again the value to be planed but in this case what I’m doing is that I’m making a focus by using the ra on that particular textbox control or you can say input control now in the return statement in the render method I have taken a text box or you can say input control which is have some value then there will be a button so let’s see the output of this particular application so if I write let’s say vull and I click on clear you can see it has been completely cleared from here so that is how you can uh use ref in reactjs okay now we’ll talk about example or you can say a demo a project where the concept which we have studied till now are let me repeat one thing jsx we talked about components props State life cycle events and Reps so out of this eight important fundamentals of reactjs we have already talked about the seven important aspects but before moving to the last reactjs fundamental that is keys that how you can use keys in reactjs let me walk you through a very good example or you can say a small project so the project requirement starts with this particular you can say example so in this example what you can see is that you have to implement a search functionality where users can search from this particular text box and whatever they are going to search it it will be visible on the screen with that search result or that search keyword now what should be the approach of yours to implement this kind of reactjs application now what is the step one my recommendation is that you break the UI into different components or you can say component hierarchy when I say component hierarchy what does it mean that you break the comp complete UI because reactjs is all about UI so you break the complete hierarchy into components component hierarchy which means that there will be a parent component there could be child or subcomponents and there could be Sub sub components so first thing first what you want to do that you will want to do is to draw boxes around every component so in this particular example what I’ve done is that I have created different colored boxes around every component and sub component component and I have given them some names also but the problem is that how do you know what should be its own component okay so by coloring this particular example we can see that there are five components in this very simple application it’s a very simple application where there could be five components so one component you can see this outer boundary of orange color so let’s say I call this as filterable product table which contains the ENT ity of the example now there is a search bar this could be my second component in the blue color the blue boundary you can see it receives the user input now there is a product table you can see the Green Boundary this is my third component this is called let’s say the product table which displays and filters the data collection based on user input now another is product category row you can see here the San color sporting goods and electronics this is my product category row which displays a heading for the each category this is my fourth component and the final component is the product row which is in the red color which displays a row for each product so now we have identified the components in this particular example now if I want to arrange them into hierarchy because components that appear within the another component should appear as a child in this particular hierarchy so what should be my hierarchy the hierarchy to break this component the particular UI is at the top I will have a filterable product table then there will be two subcomponents search bar and the product table and in the product table I have product category row and the product row so that is how we can build any reactjs application now let’s build a static version of this in react okay by creating you can say uh different different components so just want to add one thing that if if you want to make your UI very much interactive you need to able to trigger changes to your underlying data model and we are going to use it because this particular application can be made easy with the help of State what is our state the search text the user has entered this is the state and the value of this checkbox because I have added a checkbox also over here so let’s create this particular example in reactjs application so before creating this I have a sample dat dat you can say a mo data which can be used for this particular example so let’s start creating this particular application in reactjs so I’m just removing all these stuff from here let’s create this example and see how it works while using in reactjs so let me close this and I’m going to open a new instance so I’m going to open it in visual Studio code or else what we can do is we can try this example over here okay so what we are going to do is now that we are going to see that search example in this particular demo so in this particular example we talked about that we will divide the complete UI or complete example into five different components so let write those components in the create react App application so for that I have a dummy data in this dummy data what I’m going to do is first I have to create a class component the outermost that is the orange one for example let’s say filterable product with the name filterable product and I’m writing extand react do component so this will be my parent component out of the five components this will be my parent component so I’m just writing the Constructor for this class please remember all the initial State and binding of the methods needs to be done always in the Constructor only so once this is done I’m initializing or setting the initial state by using this. State you can always use this. State and can apply the properties so what are the properties I want to use the properties which I want to use is for example let’s say filter text having initial value let’s say blank and another property which I want to use is in stock only I want to check whether the products are there in the stock or not initial value let’s say false now what are the different methods which I want to bind the methods which I want to bind is for example let’s say this dot handle filter text change this is just a you can say name of the event I have to bind it to the class so I will say this dot handle filter text change dot b to this and after that what I will say this dot handle another event handler I want to bind to this particular class please remember all this needs to be done inside the Constructor only I don’t want handle filter exchange I want this time handle stock change and I want to bind it that’s it so we have defined the Constructor we have defined two or you can say we have binded two methods now it’s time to Define them so first one is handle filter text change and another is handle in stock change so these are the two methods which we are going to Define now and after that once these are defined the final thing is that you have to implement a render method for this particular class so first set the final state in this so This dot set State and there will be this dot set state so in the handle filter text change so whenever there will be a text change I want to set the final state so handle filter text change I’m going to pass text property and then I’m going to set the state so with which value I will say that filter text will be whatever be the value of the filter text now the second method which I want to bind is handle in stock change so I will have another property for it that is inst stock only and in the this. set State what I want to do is I want to set the final value of this particular property which is in stock only so I will say in stock only the property will be what whatever we passed to it that’s it so I’m done with binding the events in the Constructor setting the initial State and setting the final state in the two event handlers now the final thing is to implement the render method so in the render method I will have return statement so let’s close this return and in this return what I’m going to do is that I’m going to Define first of all a container let’s say I have defined a container now the important thing in this container what I’m going to do is as I mentioned that that I have total five components in this particular search example I have five components to be defined and this is the first component on which I working so what will be the other subcomponents other subcomponents let’s say is the search bar and another component would be the product table so you can see on the image that there is a blue boundary for the search bar component and there is a Green Boundary for the product component so let’s create those or call those components so search bar I’m saying that filter text what will be my filter text it will be this dot state do filter text now I can Define more you can say Properties or the values which are available in the initial State what are those values which are available in the initial State I have let’s say inst stock only I can Define the instock only over here what I will say I will say this dot state do instock only and then on filter exchange what I can do is that I can call my Handler what is my Handler my Handler is this. handle filter textchange and on on instock change I can again call a Handler which is this. handle instock change so that is how you can define a search bar component so this is one of the component which is defined or you can say the sub component which is defined over here the another component which I want to Define is product table so another component which I want to Define is product table now why product table if you see in this particular example this green one is the product table component and the blue one is the search component so what we have done is let me repeat once again that I have divided this complete application this complete project into five components so the first component is the first one that is filterable product table the second one is the search bar and the another one is the product table so we are as of now just calling the product table component sub component so let me Define some properties for it for example let’s say products what will be my products so I will say this do props which I’m going to Define this doprs do products so I have to Define much more values for it one is products so another let’s say I want to Define what is the filter text in this case filter text will be again same this will be this do state. filter text and then I want to Define one more property for this component that is inst stock only what will be the value of this inst stock only the value of this inst stock only will be this dot state do instock only so that is how we have defined our another sub component which is product table now as you can see how we are modularizing this particular code so first of all we are calling this filter product table in this filter product table this is the main component we are calling two sub components which is search bar and the product table so this is the main component and let’s define the main calling that is react [Music] dom. render and this in this rea dom. render what we are going to say we are going to say that we are calling the parent component what is the name of my parent component it’s filterable product table I’m going to call it and I’m going to call it on a prop what is my prop now prop is the values the Json data which I’ve already defined my prop value will be equal to products so I will say react dom. render prop value products equal to product so just I have to close this first and in fact I can close it with closing tag and then I will say document. getet element by ID the ID which I have to Define where I want to render my output that’s it so we have called the parent component by using re. render here we are passing the props as products which is my sample Json data this is the sample Json data the category of the product the name of the product and what is its price so filterable product table is the first component which we have created which is our base component or you can say parent component now the other components which we are going to create is the search bar which is the sub component and the product table component so let’s start creating those components as well so what we are going to say is class name of the component is search bar so the name of the component is search bar which extends from react. component so this is my another component and one more component which I will have which is again a sub components you can see which we have created is a product table so we can just write here class product table extends from react do component so you can see we have also created these two subcomponent which is the search bar and the product table now let’s focus on the search bar that how we are going to implement the search bar component so in the search bar component the same thing we are going to first write the Constructor and in this Constructor I’m going to define the props once this is done I’m going to call the super keyword which will have again props so this we have done now multiple times and if you want to bind some some event over here in the search bar then you can bind it over here itself so what I’m saying let’s say I want to bind couple of events over here so I will say handle filter textchange handle filter textchange so let’s say this dot handle filter exchange do bind to this and I want to have one more event handler which is handle and stock I want to check whether there it’s in stock or not so I will say this dot handle in stock do bind and this so that is how I have defined the Constructor once I Define The Constructor I have to write the definition of these events which I have written so first of all handle filter textchange this is the handle filter textchange and the another one is I want to have handle in stock change so let’s write handle in stock change now in the handle filter textchange what I want is this dot because I have the props so on filter textchange I want to pass the value which is written by the user in the text box so e do Target do value this is the value which is written by the user in the search and in the handle inst stock change what I will say that this dot DRS dot on in stock change what I’m going to write is that e do Target whether we will check that checkbox is checked or not now once this is done we will implement the render method for this particular component so I will say render and then I will have a return statement which will allow me to write the jsx for this particular class so let’s say I use a form element of HTML and then I want to implement a textbox kind of functionality so for implementing this textbox kind of functionality I’m using input input type type will be equal to text placeholder placeholder for this input let’s say equal to search just a custom text you can say now what will be the value this is something very important that what value we want so this do props what is the text which user has written this do filter text and what I want as an event I want an event on change whenever the value will change what I want to call so I want to call this do handle filter text change that’s it so my input is defined I want to Let’s Take A P tag for example in this P tag what I’m going to do is again I’m to take a input type now this time it will be of type checkbox because in this example you see I have a requirement of implementing a text box and then I want to implement a checkbox okay so I will say that this is is of type checkbox checked I will check whether it is checked or not so I will say checked equal to this do DRS do in stock only whether it is in stock or not and on change if there will be a change even on change I want to call this dot handle in stock change so that’s it and once this is done I want to let’s say for example give some space and I want to write some text that only show products in stock just after the check box just like in this example in this particular example you can see in the requirement that I want to show some static text that only show products in the stock so I have written only show products in the stock so that is how it completes the search bar component so we have written the two components as of now and now I’m going to write the product table component now this component is again very important because in this component we are going to Define two sub components more so this is our third component which I’m going to write and after that in this particular component I’m going to call two small small sub components so let me Define those components very quickly what will happen you will understand what we are doing so what I’m doing is that I will Define a very small components for example let’s say product category R so I will say product category row extends from react do component this will be my one sub component for this product table component and another would be class product row this will be again a component so extends from react do component that’s it so we have to Define these three components and our example or this complete project reactjs application will be over so what I’m going to do is first I will Define this product table so render method which is implementation of the class and in this render method what I’m going to do is that I will say Define some constants so what is the filter text filter text is this do props do filter text and I’m going to define the stock value with inst stock only which will be this do props do in stock only once this is done I’m going to Define an array of the rows so array of the rows for example I will Define with cons rows equal to an array I’ve defined an array and let’s say want Define the last category so that I have that how many categories are there let’s define it null as of now now what I’m saying that this do props dot products because products I’m passing it as a prop and it is can say Jason array so I can apply for each over here what I’m saying for each because on a array you can apply the for each so in this case I’m applying the for each and I’m on which quantity I want to apply the for each I want to apply on a variable let’s say for example product and want to apply a arrow function that’s it and I will write some conditions over here that index of filter text whether it’s in stock or not and so on I will write some of the values over here I will create a structure and before that what I can do is that I can Define this product category row so let’s define this product category row so I’m saying render now in this render method I’m defining a constant that is category is equal to this do props do category and there will be a return statement for this now in this return statement I’m just using a TR structure for example and this TR I’m defining a header with a th and let’s say some call span I can give some call span yes I can define a call span and what I’m saying is that in this th that is the table head I want to define the category so you can see here that this category is defined as a sporting goods or Electronics so I want to Define n as header that kind of functionality I I want to implement so this product category we have already defined where we are displaying the category now comes the product row now in this product row what we are going to Define so in this product row what all I want is that I want the product maybe the product name whether the product stocked or not at the same time I want the price the product price so what I will say that I want the product name I want the product price okay so let me do this and let me show you the example now so we have defined the product category and product row now you can see over here the product table we were writing the product table where product. name. index of elex equal to equal to minus one we are just comparing whether it is in the stock or not if it is there in the stock we are pushing it to the rows array so you can see here different different rows so we are pushing the values in the rows and then we are are declaring two subcomponents product category row and product Row in which we have defined the category which will be the category header and then we have Define the product row individual where we are saying that we are using the product name and then we are also displaying the product price as you can see in this example that you have to define the product name and you have to define the product price okay so this completes our demo of using the search example let me save this and open it on this screen okay npm start is this is running so just a minute the app.js I have nothing in the index.js I have the search example and in the react dom. render I’m calling this root everything is in place should show up now me refresh it okay now it is showing up so this is the output of this particular example we have implemented the five components as shown in this particular example so let’s check the output now let’s say if I want to search for football it is giving me the result for football only correct and now if I want to remove this football from the search component it is showing me all the results or you can say all the products with their prices if I check this checkbox which is only show products in stock and the products which are in trade are not in stock so it will hide those products which are not in stock for me and if I uncheck this cheick box it is showing me all the products whether they are in stock or not so this is you can say a demo which I have shown you of the complete reactjs fundamentals where you have used state where we have used props we have created the components five components we have created so for example let’s search Nexus 7 which is in another category it is giving me the result of Nexus 7 along with the product name and the product price so that is how we can create a very beautiful applications in reactjs by decomposing the complete UI into different different components this is the beauty of reactjs you can say okay so now we will finally talk about the final reactjs fundamental that is keys so what are keys in reactjs so let’s talk about the keys now so if I talk about keys keys are the elements you can say which helps react to identify the components uniquely so for example if I I have a ordered list where I have some allies I have a unordered list UL where I have some of the Allies so I can Define the keys on them so that those react elements can be identified very much uniquely so basically I can say that keys are the elements which helps react to identify the components uniquely so on the screen you can see that I have two react Elements which is having two render methods but they uniquely identified by different different keys so for one of them I am using the key as 101 um for another I am using the key as 102 so you can say that keys are the basically things which helps us to identify the components uniquely now you can see here that if any of the key is changed again I can check which key has been changed so Keys again I’ll repeat that these are the elements only which are applied on react elements specifically and they help react to identify the components uniquely okay so we’ll see the example of keys now that how we can use keys in react applications this is a example where I have used the concept of keys just to let you understand that how we can use the keys in reactjs and how they help us to uniquely identify the components and react J so in this particular example you can see that there is an array I have created const numbers uh number array with five values 1 2 3 4 5 starting from the index zero obviously because it’s an array now react dom. render this is the first method which is called in this a component is called which is the number list so number list is a component and then there are props which is used called numbers and this numbers will have this array values and then document. get element by ID now let’s talk about this number list component now this is a function based component so function number list now as you can see over here that I don’t need any state I don’t need any Constructor that’s why I have no event which is getting binded that’s why no Constructor no super keyword is used so in the function component that is number list this props is passed so numbers is props do numbers because this numbers will be taken in the props Now list items numbers do map again map is a very important you can say function when it comes to array or to iterate on the array values please remember you can use the map function this is a predefined function in jQuery and JavaScript used for arrays where you can I trate through the different value of the arrays so numbers. map number is just a key you can say now list item Now list item is again a subcomponent here I am using the key which is number. two string so I will have the key as 1 2 3 4 or five and value equal to number now in the function list item what I want to return is I want to return a list of allies having the props do value so whatever will be the value in the number that will be shown as Li but all these will be identified uniquely so if I go to inspect element I’m just showing you that how you can see here so this is a ul and this is the Ali structure which you can see over here so all these Alli structure is defined or you can say identified uniquely with this key value so what will be the key value in this case that key value will be 1 2 3 4 or five okay so that is how we can Define the key on the component or in fact you can also Define the keys directly on you can say the HTML tag for example lii so one more example if you’ll see for the keys the same example which I have shown but in this case just is a very important thing to understand that when you are returning you are returning a ul and and then you are returning the list items from the list item component this is very important to understand over here that how you are returning this ul and Alli structure in the output on the right hand side you can see the output the important thing is that we have created here two function components two function components are one is the number list which is the main component called from react dom. render and in this number list I am calling another sub child or sub component which is again a function component called function list item so function list item I’m passing the props I’m returning the Ali structure from here and I’m also returning a UL structure from where the list items will be shown so what are the list item will be shown whatever the number which are there in my array which is 1 2 3 4 and 5 so all these numbers will be shown on the screen as 1 2 3 4 5 so let’s come back to the PPT again so we talked about keys so basically we have talked about now all the reactjs fundamentals I will just again repeat very quickly for you that what all fundamentals we have talked about we talked about jsx components props State life cycle events refs and finally we talked about keys so these are all the basic fundamentals of reactjs and we have seen very good demos based on these topics one last example or you can say final demo based on these Concepts and specifically on life cycle methods which I want to show you I’m going to show you that and then we’ll start with the advanced concept of reactjs that is flux and Redux so I’ll talk about what is flux and what is Redux in detail but before that let me show you a very good example where we will be using the life cycle methods and I will show you how we can use a life cycle methods while working with reactjs so again I’ve have came back to the same example okay so what I’m doing here is I’m just commenting this particular code so that there is no confusion let’s check the output it should show us nothing now okay that’s great it’s blank because we have not return anything we have commented the complete code okay great so let’s write a fresh code now so what I’m going to do is that I’m going to show you a clock example which will completely show you the date and time but here I’m going to use the life cycle methods which I’ve shown you in the different phases so one of those methods I’m going to use is component did Mount and component will Mount okay so let’s get started I’m creating a component so I’m writing class clock extends from react. component just like we are writing every time but before completing this class component I want to write which is going to rendered on the browser or on the Dom so react dom. render what I want to show I’m I want to show this clock component so component should be always in the cly braces and then I have document. get element by ID where I want to render the output so this is done so we are sure that the first component or the parent component which will be called is the clock component that’s why I haveed the react dom. render in the first place so first thing first so since this is a class component I need to have a Constructor and then in the Constructor I want to define the super keyword so that this do props does not become undefined and then if I want to set the initial state so I have to set it in the Constructor itself so I’m saying this. State this is my initial state which I’m setting so I’m saying what is the date so I’m saying it let’s say new date so I’ve defined the Constructor now outside the Constructor what I’m going to do is that I’m going to Define a method called let’s say tick which is going to work as a ticker nothing else so in this tick I’m going to set the state so I will say this dot set State and what I’m going to set the same state of the same property date with the new date so I have set the state now in the Teck method we’ll call the Teck method later and now I’m going to Define two life cycle methods first of them is component did Mount so intellisense is helping me over here component did Mount and next I want to call is component will unmount so again intelligence I can use the intelligence great so in the component did Mount what we are going to do is that we will Define a property let’s say this dot for example timer ID equal to I’m going to define a predefined method called set interval in this set interval what I want to set is I want to Define Arrow function and that Arrow function is let’s say this dot take and I have to define the range for set interval now in component will unmount since I have to unmount the component I have to destroy the component from the dop I will write clear interval again a predefined one and in this I’m going to to pass this do timer ID so that is how we can Define the life cycle methods now once these life cycle methods have been defined what I’m going to do is default method which needs to be implemented as a part of the class is render in this render I will implement this return statement okay now in this return statement what I’m going to write is that let’s say let’s have a container so Dev is my container I will write some H1 statement example let’s say edura reactjs full course by the chin and then in H2 h2 tag another tag I want to take in the h2 tag what I will write that it is maybe with the time probably I want to say this dot state do date maybe I want to convert it probably to local time string so I and convert it to local time string and I can Place full stop also over here so you can see the output that it is showing the output adura reactjs full course by VJ it is 1129 and 50 p.m. so that is how you can use the life cycle methods in reactjs application and we have set the interval with 1 second so that’s why every time you can say the seconds value are getting changed so I will again repeat this that what I have done in this what I have done in this is that I have set the clock component in the clock component this is my parent component and since this is the parent component what I have done is that I have set the initial State and in the tech method I have set the final State now in the component did Mount and component will Mount methods there are two methods which I have defined component will unmount and component did Mount in these two methods I have said the interval that every second it should show me the the time interval what is the current time interval and in the render method in the return statement I have placed this H1 and H2 tags so now let’s come to the another concept which is flux what is flux in reactjs so let’s talk about something called flux now so till here let me repeat once again that we have completed all the eight reactjs fundamentals which includes jsx props component State and so on we have also talked about some life cycle methods how to use refs how to use keys in reactjs now what is flux now the question which will be coming in your mind is that what is flux so flux is a pattern for managing the data flow in your application as simple as that so what I can say is that there are data patterns through which you can manage the data flow in your application flux is one of them so the most important concept of reactjs or you can say in data flow that in reactjs the data flow is unidirectional by that what I mean is that data flow only in One Direction so that is the use of flux before Deep dive into this flux I want to show you one website from where you can study if you want to go deep dive into flux this is a Facebook site facebook. github.io flux this is a very good site to learn flux starting from the basics to the advanced part so I will recommend that you go through this site facebook. github.io flux this is official site from the Facebook on the GitHub okay so again coming to the PPT so we talked about flux flux is a pattern for managing data flows in your application and the most important concept is that data flows only in One Direction now what are the different parts or what are the different components in flux so flux has basically four main components one is the dispatcher another is a store another is action and the view so we will see this in detail but before that this diagram is very important this is a representation of a data flow in any reactjs application it starts from view you can see the view over here now what view is doing that view sends action to the dispatcher now dispatcher can have n number of actions n number of actions can work on a single dispatcher now the dispatcher sends actions to every store so what happens that once actions are given to the dispatcher from the view now dispatcher sends these actions to the store and then again store sends data to the view so you can see that this is a unidirectional flow of data in reactjs which starts from view through actions it goes to dispatcher and from dispatcher it again goes to store and from store the output again goes to view and that is how it works in a unidirectional fashion now we will talk about all these different components of a flux data flow one by one now what is dispatcher now as you can see in this diagram that dispatcher is getting acted upon by the actions so view is sending a action to the dispatcher so dispatcher receives action and dispatches them to stores that have registered with the dispatcher now every store will receive an action there should be only one Singleton dispatcher in each application this is very important that in any reactjs application there should be only one single dispatcher let me explain you through an example so for example user types in a title for a to-do and hits enter so we are talking about a to-do application over here implemented in flux and Redux for example now what happens is that user types in title for too and then press enter what happens next The View captures this event and dispatches and add Todo action containing the title of the too so in the title you must must have written some too that I have to Dost this task this task and this task that becomes the title of the Todo so what happens is that the view which is there in your unidirectional data flow it captures this event and dispatches a to-do action or any kind of action containing the title of the too and then when it dispatches any action it is received by a store so every store will then receive this action please remember I’m saying here every store and this will come out as a basic difference between the flux and Redux so when we will talk about Redux then we will see that Redux always have a single store but in case of flux flux can have many stores so that is why it is written on the screen that every store will then receive this action so there could be multiple store in a flux base application now what is a store we are talking about store and store so what is a store all about so store is is the place what it holds the data of an application this is the most important thing of any Redux based application in reactjs the store will register within application dispatcher so the store is getting the dispatched action from the dispatcher as an input or you can say the action is received as an input now the data in a store must only be mutated by responding to an action there should not be any public Setters on a store only Getters so action store is getting an action via a dispatcher and then store decides what actions they want to respond to every time I store data changes it must emit a change event so store then do some processing and then it decide that which actions needs to be responded to and every time a store data changes it must emit a change event there could be or there should be many stores in any application when it comes to flux but when we will study Redux please remember there is only a single source of Truth in Redux application so there should be only one store when it comes to Redux and then we can see the same example which we were talking about a to-do application so a store receives a to-do action via dispatcher now it decided it is relevant and adds the to-do to the list of things that needs to be done today and then the store update its data and then emits a change event now what are actions in any flux application we are talking about actions actions are given to store via a dispatcher dispatcher dispatches the action to the store now what are actions so basically action defines the internal API of your application what action needs to be taken they capture the way in which anything might interact with your application they are the simple objects that have a type field and some data but when it comes to action it’s very important to understand that action should be semantic and descriptive when it is taking place they should not describe the implementation detail of that action so I will say that use delete user rather than breaking it up into delete user ID clear user data and so on so remember that all the store will receive the action and they can know that they need to clear the data or refresh credential by handling the same delete user action so instead of longing the names of the action you can be very precise while giving any action to the store now this is just a action example so when a user clicks let’s say delete on a comp completed to-do a single delete to-do action is dispatched because in a to-do application some of the tasks could be completed and some are pending so when you click or when any user clicks the delete on a completed to-do a single delete to-do action is dispatched to the store now what are views so we talked about dispatcher we talked about store we talked about actions now the last thing which we want to talk about is the flux in the flux is views so this is the last component you can say of any flux data flow data from the store is displayed in views so views are the thing which is displayed on or render on the browser on the Dom views can use whatever framework you want in most example we are using the react so when a view uses data from a store it must also subscribe to change events from that store so if you remember the diagram which I showed you from view via action it goes to dispatcher from dispatcher it goes to store and from store it again goes to view so when a view uses the data from a store because in a store something has been updated something has been modified so when a view uses the data from a store it must also subscribe to change events from that store this is very important and then when the store emits a change the view can get the new data and rerender it because it has become the updated data now or the processed data so that’s why we are calling that now from from the store when the data will flow it will be the new data and which is going to be rendered so if a component ever uses a store and does not subscribe to it then there is likely a sub bug waiting to be found actions are typically dispatched from views as the user interacts with the parts of the application interface so please remember whenever there is a user interaction on The View so some actions will go to dispatcher which are dispatched to store and there will be some processing happening some changes happening in the store which is again mve to The View and the views will have then the new data which they can reenter on the browser okay so now we will talk about what is Redux in reactjs because we have already talked about that what is the flux and what are its basic concepts so let’s talk about Redux now so why we have to use Redux with reactjs as we know that react is only a view part in uh MVC model kind of application so to control the data flow we use Redux as a data flow architecture so on the left hand side you can see that there is a application having multiple components which we talked

    about and if we want to flow the data in this particular application we want Redux this is the basic use of Redux you can [Music] say so routing is the ability to move different parts of an application when a user enters a URL or clicks an element like link button icon image Etc within the application routing is basically required in transitioning from one view to another in an application in simple words I can say routing is a process in which a user is directed to different pages based on their action or request now we are good to go to understand react router react router is a standard library system built on top of the react and used to create routing in the react application using react router package it provides the synchronous URL on the browser with data that will be displayed on the web page it maintains the standard structure and behavior of the application and mainly used for developing single page web applications it enables the navigation among views of various components in a react application allows changing the browser URL and keeps a UI in sync with the URL reactjs router is mainly used for veloping single page web applications and it is used to define multiple roots in the application when a user types a specific URL into the browser and if this URL path matches any route inside the router file the user will be redirected to that particular room react router plays an important role to display multiple views in a single page application and without react router it is not possible to display multiple views in react applications most of the social media websites like Facebook Instagram Twitter Airbnb Etc uses react router for rendering multiple views to make use of react router we have something called as react router Dom what is this react router Dom which is actually the react router data object model it contains the Dom bindings for react routers in other words the router components for our websites and if we talk about react router native it contains the react native bindings for react router now moving ahead let’s see the advantages of react router because of which we are using react router so in react router it is not necessary to set the browser history manually and Link is used to navigate the internal links in the application it is similar to the Anchor tag which we know is very simple as we have learned in HTML it uses switch feature for entering and the router needs only a single child element so no complexity at all and in react router every component is specified in now talking about the installation part so what we can do is we can just go to our nodes official website and we can just download the nodejs whatever the configurations of your windows are we can just download it and once we have set up our nodejs on our PC what we’ll do is we will just install create react app okay that will be very helpful while creating the application the demo which I’m going to show you in the later part of the video in that it will be very helpful the command to install create react app is npm install hyphen G then create hyphen react hyphen app I’ll just click on this and this is how it is going to install create react app it will take quite some time but I already have it installed so I do not need it so I’ll just stop this thing over here and after that when we will start off with our demo part we will execute one more command that will be npx create react app and we’ll give the application name that we will see in later part part of the video and we’ll start off with the demo part while creating the application itself so this is what you have to do then you will have to go to the directory where you have created the application the folders so with this we have successfully installed our create react application which will help you to directly create and react application we can just add the components to that we can change the code and we can just modify it and we’ll be good to go now let’s discuss the components of a react router so there are four major components of react router which are frequently or always used whenever we are working with the react router so the first one is browser router then we have root then we have link and then we have switch so talking about browser router browser router is a router implementation that uses the HTML 5 history API which includes push State replace State and the pop State event to keep our UI in sync with the URL and it is the parent component that is used to store all of the the other components moving to root so root is the conditionally shown component that renders some user interface when its path matches the current URL talking about the link so link component is used to create links to different roots and Implement navigation around the application and it works like html’s enor tag and talking about the switch so switch component is used to render only the first route that matches the location rather than rendering all matching roots although there is no defining functionality of switch tag in our application because none of the link parts are ever going to coincide but let’s say we have a root that there is no exact in here and then all the root tags are going to be processed with which is start with slashes this is where we need switch a statement to process only one of the statements so this we will see by a demo so now I’ll just open my vs code the editor which I am using you can use whichever editor you want to use and then we’ll see how to include these components of react router on the basis of the part of URL that the router will use to track the content that the user is trying to view react router provides three different kinds of routers now we will see the types of react routers so they are namely memory router browser router and hash router talking about the memory router memory router keeps the URL changes in memory not in the user browsers keeps the history of the URL in memory and does not read or write to the address bar so the user cannot use the browser’s back button Buton as well as the forward button it doesn’t change the url in our browser it is very useful for testing and non-browser environments like react native talking about browser router it uses HTML 5 history API which includes push a state replace State and pop state apis to keep our UI in sync with the URL and Roots as normal URL in the browser and assumes that the server is handling all the request URL and points to root index.html it accepts Force refresh props to support Legacy browsers which doesn’t support HTML 5 push State apis and talking about this hash router so hash router uses client side hash routing it uses the hash portion of the URL that is window. location. to keep our UI in sync with the URL and hash portion of the URL won’t be handled by the server the server will always send the index.html for every request and ignore the hash value it doesn’t need any configuration in the server to handle roots and it is used to support Legacy browsers which usually don’t support HTML push State API and it is very useful for the Legacy browsers or we don’t have a server logic to handle the client s and this route isn’t recommended to be used by the react router dting and the Syntax for these kinds of router we will see just in the import statements we just have to change it and we will elas it as router let me just show you now what we will do is we will set up our react application so we’ll create a react application using Create react app and for that let me just go to my command prompt there let me just go to the desktop so I’ll change the directory over here I’ll move to desktop and then I’ll run this command npx create hyphen react hyphen app and let me call this app as edira routing now this command will create so now here you can see is we cannot create a project name _ routing because of the npm naming restrictions name can no longer contain capital letters so we’ll just give it as Eda routing now here you can see creating a new react app in this folder okay inside the desktop we’ll be getting folder for react application that will be known as Eda routing and it will take some time it will actually take sometime like around 2 3 minutes and once this will be done then what we’ll do we’ll move to our this application folder that is AA routing and then we will install our react router Dom which I had explained you it contains the Dom bindings for react application we’ll make use of npm and we’ll install react router Dom and then we’ll start adding the components I’m using the visual code Visual Studio code AS editor you can make use of any other editors as well now as you can see the dependencies have been installed and you can see over here as well like some 29 packages have been added so with this create react app we can simply create our react application and we can just add the codes we can add the components and we’ll have our react application created with this we have successfully created our react application and the name of our react application we have given as a Rea routing okay as we are going to learn routing with this so with this you can see over here happy hacking and now we are good to go now what I will do is first we will move to the project directory or the application directory which we have created right now we’ll give CD and edore routing and now what we’ll do is we will install the react router Dom for our this application so we’ll give npm install react router D okay router D and we will give a space and hyen save this command we have to give all right this will install our react router Dom for our existing application which we have just now created with the help of create react app it will also take some time but less than the previous one and yes with this we have successfully installed our react router Dom for our our Eda routing application now what we’ll do is now we will start creating or adding the components to the application now what we’ll do is I’ll just close this up and in my vs code I’ll open the folder which has my application so in this yeah in desktop you can see Eda routing is there I will just open this one now here you can see our application or the main folder is edore routing then here we have node modules all these libraries and the pendencies are here like you can see Babel and all for es6 and all we have just for testing so all these are available they have been automatically added with the help of create react app and then here in this public we can see here is the index.html so if we want to change the title or the HTML part of our application we can just make changes over here or we can just create the new one we can just create a whole new code as well so I’m not going to all this HTML and CSS part majorly because we are here to learn about routing first what we’ll do is we’ll go to our SRC folder and here you can see we have app.js file so this component this is actually where we will be using routers react routers we are going to make use of them over here in this application so that we’ll provide the links and the switch and everything which will be linking to the other components so what we’ll do is first of all let me just remove whole code because this is a default one this create react app is for the default one it is like reacts default application which has been created now we have to create the components add them with the help of routers and all now first what we’ll do is we’ll import our router so what we’ll do is we’ll write import so as we have learned about the routers so we’ll give browser router as we have seen this is the first component of react router so we’ll give browser router and we’ll alas as router then we have the other component that is root then we have link and then we have switch and this we have to get from react router Dom now here be clear with the thing that here this browser router is elas as router now to use react router what we’ll do is we’ll create some components in this react application so what we’ll do is inside our this SRC folder what we’ll do is we will create one more folder and that we will make it as comp component so we have one more folder inside the SRC that is component now here in this we’ll create other files other JS files which are actually the components so let me just add one file as home.js then we will create one more about. JS and then we have contact. Js so these three components I have added now let’s add some code to this so that will be available on the screen whenever we will be executing our application so let me just go to home and let’s add some code like first thing is we have to import react from react and then we will write the function or the reducer we know function home which return heading we’ll write like welcome to Eda and that’s it and then we’ll close this function and we’ll write this export default app default we’ll just save it and then next is our about component so in this will’ll simply let me just copy it from here we’ll just paste it and we’ll make the changes over here here is about now let me write let me write something about Eda so Eda is in e-learning platform and let me give you some more thing like like know more about Eda here now here we I’ll make use of the anchor tag and I’ll give the link [Music] http://www.ed now here we have the link and I want to display this as well so what I’ll do is I’ll just type it over here as well and with this we have closed our anchor tag now when we have created this one and the anchor tag is closed over here now one more thing is we have to return something so here in return I’ll put all this inside a div so this one is also ready and here I’ll have to give this about the function which we have just now created let’s save it and now moving to our contact component so again let me just copy this thing and we’ll put it here now here what I’ll write is like for queries contact here now no link I don’t want to give any link over here now let’s just put the number let me just put this over here and one more thing see and if I want to put it in the next line and all so I can just give the BR tag as we know in HTML and no need to give it like this let me give one more yeah now in this about what we’ll give is we’ll give the in place of about we’ll give contact me just remove this anchor tag now let’s make a little change over here let me just put it inside the address so that it will be like a single element over here and let’s just remove this heading tag all right and we’ll just give it up so we have created three components and we have added them the home component then the about component then we have our contact component now in this app.js what we’ll do is we will make use of our react router and then we will link these components now what we will do is we will start adding the components to our app.js the components of react router over here now as we have already added this browser router as router now let me just create class app extend component and then we’ll give it as render we’ll make use of render function then we’ll return router and inside a div we provide the class name let’s give it as app and then we have closing tag for rter now moving ahead what we have to do is inside the div we have to put the links as well link is also one of the component of react router before moving ahead we can just see let me explain you the components which we have created especially talking about the props associated with the root component we’ll see over here as you can see the exact right this this is used to match the exact value with the URL for example here we have given exact and then the path that to home component and this will only render the component if it exactly matches the path if we remove exact from the syntax then UI will still be rendered even if the structure is like slash and home like that and then we have something called as path over here so this specifies a path name we assigned to our component the path name which we have assigned like contact home about like that and then we have something called as component it refers to the component which will render on matching the path these components which we already have contact home about out all these and as we have seen in this we have switch as well this switch will be used to render a single component wrap all the roots inside the switch component so we have just wrapped it around and this link we have used to create the links to our components it uses the two prop to describe the location where the link should navigate so here you can see this two prop this two prop has been used by this link component now let’s see the output of this application or this code which we have written now we will see the UI of our application it’s taking a little time so it will get executed browser will be launched here so you can see over here on Local Host 3,000 it will be launched here it comes now this is the page okay now whenever I’ll click on home now we have moved to our homepage this is happening with the help of our router the components which we have used the link component we had made use of browser router and the switch now when I click on about us here you can see the URL is also changing and with this if I’ll click on this link so this is the normal HTML link part with the help of anchor tag I have just redirected to our Eda homepage let’s just go back and then on contact us you can find it over here so whatever we wanted to display in our application that’s been displayed in the different pages and we are redirecting to these pages with the help of react router and here is the URL and the application name is like react app we can make change in that also let me just go to this one and in the index.html we can just change the name of the title like we can change the title let me just give it so here I’ve just made it as Eda let me just save it and then it will automatically be reloaded here you can see now the name of the application is your Ed over here so this is the output which we are getting so this is how finally we have successfully implemented the navigation in our react app application using the react router now as earlier we have talked about the types of react router so let me just show you here so as you can see in this app.js we had made use of browser router so we have hash router and memory router what we have to do is just in place of this browser router we can just simply put memory router and everything else will be same and we can just elas it as router similarly for hash router we just have to make change in hash in place of memory I have kept it as hash now it became hash router and the functionalities which are supported by hash router memory router and the browser router will automatically be implemented so no need to change anything else we just have to import that type of router and we will elas it as router itself and we have already discussed what are the functionalities and how these routers are implemented according to their [Music] types now let us go and explore all about reacts hooks starting from what is reactjs hooks reactjs hooks are functions that allow you to use the state and other react features in functional components they were actually introduced in react 16.8 has a way to make it easier to share the stateful logic between the components and also to make it easier to work with the functional components here the most commonly used hooks are the use State use effect and use content so these are considered more important or most useful hooks so other than this we will also explore some of the additional hooks too for example use reducer use memo use call back and use layout effect so these are the hooks that we will be exploring in this session we will see each of it in a detail form right now before that we will see what actually the hooks are now let us go back and see before react h hooks so before react hooks if you wanted to use the state or other features in the component then you had to use a class component here the class component are more complex than the functional components and can make it difficult to reuse the stateful logic here with the react hook you can use the state and other features in the functional component which makes it easier to share the state full logic between the components and also it makes it easy iier to work with the functional components here the react hooks differ from the traditional react class component because in that they allow you to use the state and other features in the functional components instead of having to use the class components and additionally you must keep this in mind here the react hooks do not require the use of this keyword which makes them less verbos and easier to understand and why do we say here the class component is more difficult so here the class component in react are based on this JavaScript class syntax which can make them difficult to understand for the developers who are new to the react or who are more familiar with the functional programming additionally these class components often include the boiler plate code such as the Constructor functions and binding the methods to the correct context which can can add unnecessary complexity and make the code harder to maintain and the most important feature of this react Hook is it allows the creation of custom hooks which are reusable functions that can hold the state or the logic that can be shared between the multiple components here this makes it easy to extract and reuse the logic that is used in the multiple components so at the end this can make the code base more maintainable and easier to understand one of the main advantages of react Hook is that they make it easier to share the stateful logic between the components as I said in the previous statement so this is because the state and the logic can be extracted into a single hook and it can be reused in multiple components rather than having to duplicate the logic in multiple class components react hook also make it easier to test the functional components since they do not relay on this keyword and the life cycle methods now let us see the types of hooks we have in this session here we have three major hooks that is use State use effect and use context so these are considered to be basic Hooks and more important hooks or commonly used Hooks and additionally we will also look into use reducer use memo use call back and finally use layout effect so these are the hooks which we will be covering in this session other than this we also have many other hooks so if you want to learn more about hooks or more about react years you can enroll to our edura react years certification training course where we will be providing you with an Hands-On and a live demo sessions so here we will get started with our first hook that is use state so let us see what is use State and how does it work in our course code and I will give some of the tips that how can you use the use State inside the code now according to the definition use state is a hook in react that allows you to add the state to the functional component state is a way of storing and managing the data that can change over time and can affect the components behavior and rendering though I will explain it in a detail form here this U state is a hook in react that allows you to manage the state in the functional component prior to the introduction of HS the State Management in react was only possible in class-based components so with this use of use State you can now manage the state in the functional component as well and also the U state is a function that takes a single argument so which is the initial state after that it returns an array with two elements that is current state and a set a function for updating the state the current state is a value of the state and the setup function is used to update the state so here I will explain this in a detail form with an example so I’m using visual studio code so here I will show you a small demo for that I will jump into Visual Studio code now as you can see I have already created a app called counter app so you can see here the counter app and here I have created a counter. GSX inside the source folder and inside the components folder now let us write a small react hook example first I will import the react component from react for that write just import react from react okay after that I will import UST State Hook from the react package after this line for that you just need to write Import in the bracket U state so you will have some of the recommendations over here and you need to find U State over here so State and you can notice that I’m writing in a camel case statement here the react GS takes the input in a camel case after this now that we have imported the component and use state from react at the same time we need to export this file file to the index.js right so that the output will be shown in the browser so that don’t forget to export this file to the index.js so I will export so just type export default counter because my file name is counter so I’m writing counter and you just need to go inside the index.js and include the counter file inside the react strict mode now let us get back to the counter. JS file so now let us declare a new state variable so let us call this as count here the U State returns a pair of value that is the current state and the function that updates it as I said in the explanation so that we will just write a function called counter inside that just write const and pass the values that that is the current state and the function that updates it right so here the current state is this count and then we will set the count so this will be the function that updates it and in our component we use the U State Hook by invoking it and passing the initial value for our state variable which is zero so I’ll use that so I’m using the use state so I’m passing the value as Z zero okay now let us return this so I’m wrapping this with a div tag now here we use the count variable to display the current number of Clicks in the page and in the button tag here we use this onclick property to specify a function that will be called when the button is Click right now for that I will write a paragraph to indicate the numbers so I’m writing you click here I’m calling the count and this count will be indicated in numbers so you have clicked this many times so right so so I will give the button to click so on click so I’ll set I’m calling this set function so that is set count this s should be in the small here the function that we pass to on click is an arrow function that calls the set count and passes in the new value of the count so which is the current value + one so let us write the count that is the current value and + one so whenever the button is clicked here the count will be incremented like the current value + one so the count will be incremented to one so I’ll close the button by telling click okay so let us run this by typing npm start and you can see the server has started you can see that we have written you clicked this many times right so let us click this button and check so here you can see the number is incrementing so if I click on this the number is changed the value to two so that the current value is right now is two so if I click the button once again the number will be incremented + one so that the current value + one will be incremented so here as you can see the count this is the current value and plus one so every time the button is clicked this function will be called and the state variable count will be updated and here the component will be rerender to reflect the new value so I hope you understood now I will give you some of the tips to use the use State here we have some of the limitations for example keep State update simple here you need to avoid the complex Logics or the calculations when updating the state instead use a call back function to update the state based on its current value and next so you need to keep in mind that you need to use the use State when it is only necessary here use props or the context when possible instead of creating the state for every piece of data after that you need to use the use effect hook for the side effects keep the state top level that means you need to keep the state at the top level of your component hierarchy as opposed to bury deeply in class component this make it easier to understand and debug the code easier and you need to keep in mind that you need to test your component always you need to test your component to make sure that they work correctly and the State updates are behaving as expected with that we will move on to the next hope that is use effect now let us explore about use effect here this use effect is a hook in react that allows you to synchronize a components with an external system also it will allow you to tell that react to run a piece of code after rendering in order to update the system or the side effects of the component so this is done by specifying a call back function that contains the code to run and an array of dependencies which are variable La that components uses and that react will watch for changes now when the component is first rendered the call back function passes to the use effect will be run this is similar to the component did Mount life cycle method in the class component if any of the dependencies specified in the dependency array change react will rerun the effect now this is also similar to the component did update life cycle method in the class component so as I said before here we have class did Mount class did update and class did unmount so these life cycle methods are used in the class component so here the next life cycle I’ll be explaining is component will unmount here when the component is unmount the cleanup function pass to the use effect when it will be run this is for cancelling Network request or cleaning up any other side effects that we created now that we will understand this use effect hook with a small example so I’ll go back to the visual studio code I will clean up the use State I will keep the react component and the export has default now we need to use the use State and use effect from the react so for that we will import use effect along with the use state from the react react package after the react component line so that I will just import inside the curly braces right use F and use state right in our component we declare a state variable data using this new state and and the initial value is an empty array so for that we will just write a function for that counter so for that I will be setting the constant values here and I’ll pass both width and the set width as I said the current value and the function that will be updated so here withd is the current value and I’ll set the state so now what does this line mean so here I have written this line right now this means that I’m taking the windows inner width so let us see for example I want the inner width of the browser and I need to design a web page where my grid needs to match it so I need to know the width of my system or the browser so that I’m taking the inner width of the browser now let us fetch the use effect I’m taking the function handle resize so we need to know the size of our window right so that is why we are using this function function handle now I will set the WID for window inner width here the set with function update this date when the browser window is resized now let us set the window uh event listener here use effect Hook is used to add an event listener to the window that is listens for a resize event and when the resize event is triggered the handle resize function is called for that we are writing a code here so for that window dot add event listener and I’m specifying here resize here as I said when the resize is triggered the handle resize will be called to update the width of the state in the new value of the windows inner R now here let us clean up the function to remove the event listener here now I will return here I will return the remove event listener here I’m specifying this window do remove event listener here the empty array at the end of the use effect is the dependencies it means this effect only runs once on the component mode right so here now I will return this also so I’m WR the windows width will be so I’m calling this width function here here the component returns a Dev that displays the current width of the browser right now let us check out the results here the window width is 614 now let us resize this here here as you can see if I resize the windows WID changed to 335 so if I again resize so it will change according to that so it will not change the height so as if we have just set only for the width the total window width of my system is 614 so if I resize so it will change according to the size we moveed to so I hope hope you understood the example with the use effect here some of the tips to practice this use case in a best way for that you need to First understand the purpose of the use case of the use effect hook here it is used to handle the side effects so as I said in the example such as the data fetching in a functional component and always you need to include a dependency array as the second argument to the use effect and this array should include any variables or state that the effect depends on here if a variable is not included in the dependency array that the effect will run on every render and you should be mindful of the order in which effect runs here this effects are executed in the order that they defined so it is important to consider that the order of your effects if they are dependent on each other and you should use the cleanup function provided by the use effect to remove any side effects before the component is unmount so this is especially important for the data fetching and subscriptions to prevent the memory leaks so as I did here in the example I did the cleanup function to remove the event listener right so like that and also you should keep in mind that the excessive use of use effect can lead to unnecessary re vendors and it can be slowed down your applications and also you can use the use context who instead of use effect when possible here the use context is a simpler and more efficient way to manage the shade State across the multiple components that is what we are looking next we will look into the use context here now let us see what is use context it is a kind of H that is used to consume the context in a functional component it is an alternate to the context type property or the consumer component that we used in the class component here when a component needs to access the context it can use the use contact hoop to describe to the context and retrive its current value the hoop takes the context object has it argument and Returns the current value of the context the component can then use this value to update its state or props the use context hook allows a component to subscribe to changes in context so that it can rerender when the context value changes so this is done without the need to pass props down manually through every level of the componentry which makes the code more efficient and maintainable here when a context value changes the react will re render all the components that are using that context this means that the component using use context hook will be rendered to which is how the component will get updated with the new context value now if I summarize the use context the use context hooks allows the functional component to access the context and the subscribe to changes in context it also eliminates the need to pass the property through the multiple levels of the component Tre eventually which leads to more efficient and maintainable code now let us see a small example so let us go to visual studio code and I will just remove from the function so default let us keep import Rea component from Rea here in import we will just import the create context with use context okay so now let us create a context with a default value for that I’m writing the const and theme context here we use this create context to create a new context called this theme context okay with the default value of light so I’ll keep the default value as light which is equal to create context to light right fine now let us create a function counter now let us use the context to access the current theme right so that I’m specifying the cons now the theme is is we are using the use context in theme context here in our example component we use the use context hook to access the current value of the theme context right so here we have light so we need to access this light in this theme context here we will return the div so let us specify the class name as uh theme right and let me write something like the current so we need to get the uh output from this theme so when the value changes here the value here will be also changed accordingly now here let me write a function called app and return the theme context dot provider value is dark so I’m specifying the counter over here inside the theme context right now let us see the output here as you can see the current theme is light right we access the value of the context in this case here the theme and we use it to set the class name of the div element and in the app component we wrap the element component with the theme context provider and set the value to the dark okay here now whether the value is provided to the context will be available to all the components that are wrapped inside the team context provider and all of them will be able to access the current value of the context by calling the use context and theme context okay now here some of the tips to practice the use context here to keep the context value minimal Only Store the values that are necessary for the components that are consuming the context and you need to avoid the storing unnecessary data as it can lead to unnecessary rerenders and performance issue and also you need to use the default values always provide the default values for the context when creating it in case that consuming the component does not have access to the context now you should use the use context for Global state so that it is shared across the multiple components such as the users authenticated status or the selected theme also you need to avoid using context for local state here use State hooks for local state that is specific to single component rather than using the context only update context when necessary you should only update the context when the value has changed to avoid the unnecessary rerenders and performance issues here you need to use the use effect hop to update the context the next we have the test context test the context value and update to ensure that they are working correctly here we use the test context to test the value that were updated correctly and whether it is working correctly now then we have the use multiple context so here if you have m multiple pieces of global State and that need to be shared here we need to consider using the multiple context to keep the state organized and easy to manage with that we will move on to use reducer who here the use reducer is a hook in react that allows for managing the state within a functional component here it is similar to use state but it is typically used for more complex State Management and the state red rer hook takes two argument a reducer function and a initial State here the reducer function is a pure function that takes the current state and an action and it Returns the next state the initial state is the starting state of the component State a component can call the dispatch function returned by the use reducer to send an action to the reducer here the reducer that updates the state based on the action and the current state and also the component reenders with the new state the use reducer is considered more powerful than us State because it allows for more complex State management such as handling the asynchronous actions and managing the multiple pieces of State at once in short the use reducer is a hook that allows you to manage the state within a functional component in a way that it is similar to how you would manage the state in a Redux store it takes two arguments a reducer function and an initial State as I said initially and Returns the current state and a dispatch function that can be used to update the state now with that let us look into a small example so let me remove from the import again let us import the use reducer package from react after that we create a reducer function that takes in two arguments that is State and action here which are the current state and the action that is being dispatched respectively okay so that let’s write const so initially I’m setting the value to count zero so initial state is count zero fine after that the function the function reducer State action after that I have switch case in that I will write switch I’ll write action type if that is the case then the case should be in increment then I will return the count to the state count + one if the case is in the decrement then I will return count State minus one then default I will return the state first let me write the code and I will be explaining you each and every statement here right so that first here I’ll write the function here as you know the use reducer hook returns a pair of values the currenty State and a function that updates it in our case we use the destructuring assignment to assign the state and dispatch right here we use the state count to display the current count in the page and in the button tag here for that I will specify the page and the button tag here for that I’m returning a statement so return here I’m writing in the count here count and the state count now let us specify the button for increment as well as the decrement here on click let us write the dispatch so this type will be in increment fine now for the same I will give for decrement right see here here I am giving the decrement so after that the div is closed so here the function that passes in the on click property to specify a function that will be called when the button is clicked so I’ll be showing that in the output page here the function that we have passed to on click is an arrow that function calls dispatch and it passes in the object that describes the action that should be performed here in this case the action type is either increment or decrement right so when the component is rendered it was initially the number is zero the count is zero so when the button is click in the increment so it will call the dispatch function with the type increment and the reducer function will receive the action and the state so that it will update the state and increment by one so see for example if I go to the output so if the button is clicked in the increment so the count will be two for example if I increment one so the count will be + one right so when the minus button or the decrement button is clicked so it will call the dispatch function to the decrement then the reducer function will receive the action and the state so it will update the state and decrease by the count one and the component will rerender and it will show us the output as minus1 so count minus1 so here keep your state and the action simple now let me give you some of the tips here you need to keep your state and action simple the use reducer is designed to handle the complex State and actions but it is important to keep them as simple as possible to avoid the confusions and make it easier to debug and also you should use the initial State correctly make sure to provide an initial state that is the same type and shape as the state in your reducer function and the use actions to change the state you need to use the actions to change the state in your reducer so do not modify the state directly as this can lead to unexpected Behavior also you need to keep your reducer function pure so what that your reducer function should be pure means it should not have any side effects and should not relay on any external state or variables so with that we will move on to the use memo use memo is a hoop that allows you to optimize the performance of your react component by only recalculating a value when one of its dependencies has changed now it is similar to the use effect hoop in that it allows you to perform a side effect but instead of updating the component state or props it returns a value that can be used by the component here the use memo hook takes two argument as previous hook sticks the first one is a function that returns the value you want to store and the second one is a array of dependencies the function is only called when one of the dependencies has changed if none of the dependencies have changed the previous value is returned instead of recalculating the value for example if you have an component that displays a list of items and the list is passed in as a prop you can use the use memo to only read ref filter the list when the search item changes instead of ref filtering the list on every render now let us see a small example so now let us go to visual studio code I just have import react component from react and I have exported the counter now let me import the hooks from the react so I’m importing use State and use memo right now let us just Define a functional component called counter okay so function counter now let us create the state variable for first name last name and H so that constant first is our first name then I will set the first name here I will use the use State same thing for last name and H I am giving a empty parameter over here so that it is dynamically updated when the user enters the first name last name and the H okay right now let us calculate the user object over here so now let us see this function will uh run only if the first name last name or the a state variable have changed so I’m giving the uh user also so const user by using the use memo so let us return turn the full name the full name consist of the first name and the last name and finally AG right in the array I’m just giving the first name last name and age return inside the diff I’m just giving the input value for the first name last name and the H here the component also uses the use memo here right so this hook can create a memorized object called the user so that is why we have specified the user over here and that combines the first name last name and the age the state variable into a single object with properties that is first name and the age the components then renders input field that allows the user to update the state variables and display the user object so that is what so here I will be giving the input values over here here first one is the first name on change so if the value is changed then the output should be rendered here in the age we have to type the number so the input value will be in the form of number right then let me give a paragraph inside saying the full name and the h now let us see the output so if I show you the output here I can type my name so here in the full name you will get uh the first name and this is the last name so for example I’ll type V so as you can see the full name I have written in the first name as T and the last name has v so in the code here here it should return in the name of full name is the first name plus the last name and the age right so here if you see uh in the place of first name I have typed only my first name and in the last name and in the place of H since I given in the input has numbers so it will tell you to increment or decrement or else you can even type the number so in place of age you have the number over here right for example 46 yeah and you can increment or decrement as you need so in this code the react functional component is called the counter right so it uses the react hook called use State and use memo to manage and update the component State and to perform a calculation based on the state here the component has three state variabl that is the first name last name and H so which are initialized using the U State now these State variables are used to control the values of three input field rendered in the component jsx that is these three input Fields here the component also has a user variable so here you can see the the user variable right here the function concatenates the first name and the last name the state variable to create the full name the property of the user object and the user age that state variable as the state property the second argument of the use memo is array of dependencies which is used to determine when the calculation should be rerun in this case the calculation will re run only if the first name last name or AG State variable has changed the component reenders and input field from each state variable and displays the full name and age property of the user object right with that we will move on to the tips for use memo use the hook called use memo when you need to compute a value that depends on or state but not change often always pass a function that runs the value you want to memorize has the first argument the function should take the props or state that the value depends on an argument and the use mve with the second argument an array of dependencies to tell that react which values the memorized value depends on so this will ensure that the memorized value is only recalculated when one of the dependency changes avoid using use memo in render functions as it can lead to poor performances instead you can use it in the component functions that are called before the component rerenders also you need to use the use memo with the caution when working with the large data set or the complex computations as it can cause performance issues if not used correctly and avoid using the use memo to store functions as they cannot memorize instead you can use the use callback hook for this purpose now let us see use callback hook use callback is nothing but it is also a react hook that allows you to optimize the performance of your react component by only recreating a callback function when one of its dependencies has changed it is similar to use memo but that allows you to store a value and only update it when the dependencies has changed but instead of storing a computed value it stores a call back function here the call back hook takes two arguments the first one is a call back function that you want to store and the second is a array of dependencies here the function is only recreated when one of the dependencies has changed changed if none of the dependency have changed the previous call back is returned instead of creating a new one for example if you have a component that displays a list of items and the list is passed in as a prop you can use the use call back to only recreate the function that handles the recreating the function on every render but it is important to note that the use call back is often used in the conjunction with the use memo when the dependencies are object or the function to prevent unnecessary rerenders and recalculations as use memo only recalculates the value when the reference to the object or functions changes now let us see a small example for use call back hook and import the hook packages from react that is I’m using the use state and use call back from react now the function called counter let us initialize the count and the increment value here right so that for here I’m writing the const so I’m I’m setting the count as well by use keys by use US state and the next one is increment I’m using the use call back function over here let’s set the count to count + one because we are incrementing it right so right now let us return with a Dev tag inside that I’m writing H1 tag so I’m telling the count value then I’m specifying the child increment after this we have the child increment over here as you can see right so that I’m creating a function over here called child inside that I’m just passing an argument call increment by returning a button with a onclick function increment right now in this example the parent component has a state variable that is count so as you can see here we have count this is the parent component and the call back function is the increment that increments by one so here the count plus one so as you can see this is the parent component plus incrementing by one here the child component receives the increment function as a prop and renders a button when click and it calls the increment function over here the use call back Hook is used to memorize the increment function passing in the count as a dependency this means that the increment function will only be recreated if the count State variables change so this can help to prevent the unnecessary rerenders of the child components when you run the code the output will be a increment button and a H1 tag saying the count is zero so when you click on the button the count will be increasing by one and the H1 tag will be displaying the updated count right so if you can see I’m clicking on increment and the number changes to two by increment + 1 so 1 + 1 is 2 okay so right now let us see some of the tips so here use the use call back when you need to pass a call back function as a prop to a child component and you want to avoid the unnecessary rerenders always you need to provide the dependency array has the second argument to use the call back this tells the react which variables the call back depends on and when it should recreate the call back and also you need to keep in mind that the dependencies you include in the array if you include too much or unnecessary dependencies it can cause the unnecessary rerenders and negatively impact performance and you need to avoid the use call back inside the loops or conditions as it can lead to unexpected behavior and hard to debug the issues and always you need to check if the call back function is the same using the reference equality operator before passing it to a prop so this will prevent the unnecessary rerenders of the parent component you need to be careful while using the use call back function with this the state or prop that are objects or array because these are passed by references not by values so if the call back depends on such variables it will be recreated every time the parent component reenders and you need to be aware that the use call back does not work with async functions because it cannot memorize the results of asynchronized operations always test your component with and without use call back to check that if it works has expected and that the performance improves you expect as visible right okay now let’s move on to the last hook in this session that is use layout effect now what is use layout effect use layout effect is a react ho that allows you to synchronize all layout changes to a component here it is similar to the use effect but it runs synchronously after all Dom mutations now this can be useful when you need to measure a Dom node or read its layout before making changes that affects its size or position also it should be used with caution as it can cause visual inconsistencies if not used correctly and also it is recommended to use use effect unless you have a specific use case that requires the synchronous behavior of use layout effect so you need to be careful while using the used layout effect and also importantly to note that the used layout effect should be used only for updates that are critical to the visual appearances of the component and that cannot wait until the next frame for all other updates it is generally recommended to use the use effect instead with the run asynchronously and does not block the main thread and also so it is important to remember that if you need to perform any side effects that involves the Dom such as adding or removing the event listeners you should do so inside the use layout effect instead of use effect this is because the use effect runs after the browser has painted and may cause unnecessary layer thrashing if it updates the layout of your component okay with that let us move on to the example now this code is a simple react functional component that uses the use layout effect and the use state so here it uses these both hooks to measure the width of an element and display it in the screen okay the first code Imports that the layout effect and the use State and the use ref from the react Library right here the U state is a hook that allows you to add the state to a functional component in this case it is being used to create a state variable called WID and that will store the width of the element here the UST State hook also returns a set width so that can be used to update the value of the width State variable here now the use ref is a hook that allows you to create a reference to a Dom node so in this case it is being used to create a reference to a div element that will be used to measure the width of the element over here here the used layout effect is a hook that allows you to synchronize and apply the layout changes to the component so it is similar to the use effect as I mentioned earlier but it runs synchronized after all Dom mutations so this can be useful when you need to measure a Dom node or read its layout before making changes that affects its size or the position so this component start with the div element with the ID my element and within the WID State variable is displayed and use layout effect is then invoked so inside the hook the code first gets a ref reference to the element with the ID called my element using the document. get element by ID inside the my ID this used layout effect Hook is then invoked inside the hook the code first gets a reference to the element using the ref variable called ref do current you can see here this ref dot current then it uses the get bounding light ring right this method to measure that the width of the element and assign it to the variable width after that the set width function is invoked with the width variable as an argument so which updates the state variable with the width of the element here the used layout effect hook also accepts a cleanup function which is a function that runs when the component is unmounted or the effect is being rerun so this is that function okay so the cleanup function will also display the cleanup in console so when you inspect in the console then you will get to know about it right and also you need to keep in mind that uh it is important to note that the used layout effect hook should be used with the coction as I mentioned so as it can cause the visual inconsistencies if not used correctly so it is recommended to you to use the use effect unless you have a specific use case that requires the synchronized behavior of the use layout effect and it is important that if you don’t provide a dependency array the effect will run on every render so which could lead to a performance issue so it is better to provide a dependency array with the values that the effect rely on so that it only runs when those values changes okay so it should not run whenever the small changes happens the whole program will run so right in this example an empty dependency array so this is the empty dependency array so it is passed to a use layout effect ho so which means that it will only run the code once when the component is first rendered so in this example instead of using the document. getet element by ID to find the element it is passed to a reference to the element as it uses the ref dot current dot here the ref dot current dot get bounding client R so to get the width of the element so let us see the output over here so we have to run so after that so as you can see the width of the element is around 613 Point 44 okay so let us inspect this here you can see as I mentioned you will get a console here we have console right as you can see here the cleaning up function as I said in the program right here you will get the clean up function here so inside the console you will get the cleaning up [Music] we should know why to use Redux react is one of the most popular JavaScript libraries which is used for front-end development it has made the application development easier and faster as it follows the component based approach where the data flows through the components basically react follows unidirectional data flow that is data always flows from parent to child component where child component can never pass data back up to the parent component as you can see on the screen the colored circles are representing the components where the upper component is the parent while lower ones are the child or subcomponents the view cannot interrupt in the data flow so data Flows In unidirectional fashion here data flows from parent to child react does not provide any way for direct component to component communication although react has features to support this approach but it is considered to be a poor practice as it is prone to errors as you can see on the screen a child component can never pass data back up to the parent component and here is the catch so the question comes is how can two non-parent components pass data to each other this is where Redux comes into the picture as you can see in the picture a store is a place where you can store all your application State together now the components can dispatch State changes to the store and not directly to the other components then the components that need the updates about the state changes can subscribe to the store so we can sum up into the points as produx offers a solution of storing all your application state in one place called a store components then dispatch State changes to the store not directly to other components and then the components that need to be aware of State changes can subscribe to the store Redux helps you manage Global state that is actually the state that is needed across many parts of your application Redux separates the application data and business logic into its own container in order to let react manage just the view react gives only the view in MVC model where MVC stands for model view and controller so we can say react is just the view and to control the data flow we use Redux as a data flow architecture as you can see on the screen react is responsible for the view that is the web application on the browser and Redux controls the data flow now let’s understand understand what is Redux Redux is a pattern and library for managing and updating application State using events called

    actions Redux separates the application data and business logic into its own container in order to let react manage just the view it’s an application dataflow architecture Redux was created by den abov and Andrew Clark around June 2015 it was inspired by Facebook’s flux and influenced by functional programming language Elm it got popular very quickly because of its Simplicity small size as of 2 KBS and great documentation this is the basic idea behind Redux that a single centralized place to contain the global state in your application and specific patterns to follow when updating that state to make the code predictable so basically the patterns and tools provided by Redux make it easier to understand when where why and how the state in your application is being updated and how your application logic will behave when those changes occur Redux guides you towards writing code that is predictable and testable which helps to give you confidence that your application will work as expected now let’s look at the principles of Redux Redux follows three fundamental principles where the first one is single store or we can say single source of Truth the second principle is state is always read only and the third one is changes are made with pure functions or reducers now let’s understand these principles in detail starting with the first principle that is single store so when I say single store it means that all my applications state are stored in a single immutable store as with only react unidirectional data flow direct communication between components is not allowed now the state of the entire application is stored in an object or state tree within a single store components state is stored in the store and they receive updates from the store itself so components dispatch something to the store and then the other components when they get to know that something has been updated they subscribe to store now let’s move to the second principle that is the state is read only which means the only way to mutate the state is to emit an action which describes the user’s intent hereby muted I mean is to update so we can say that we can change the state by triggering an action which is an object describing what has happened as you can see on the screen here the action is no action and when the action is switch on the bulb is getting lighter now let’s talk about the third principle that is change using only pure functions in Redux pure functions are called as reducers the reducers are used to indicate how the state has been transformed by action the reducers or pure functions take two parameters as input which are the previous state and the action so when it takes the previous state it gives us the new state as you can you can see in the picture the previous state is that the bulb was not on and then it has been worked upon by the reducers and then we get the new state that is the bulb is on now I’m going to talk about the components of Redux Redux has four components action reducer store and view so let’s understand these components in detail starting with the action action of the plain JavaScript objects which are payloads of information for the store so basically the only way to change the state content is by emitting an action as we have already talked about it so here action means plain JavaScript object which are the main source of the information which we use to send data and data could be user interaction internal event like API call or form submission we can send these from the application to the store and then the store receives this information only from the actions and then we have to send the actions to the store by using store. dispatch for example here as you can see we Define the type as ADD too and then we can Define the parameters as Text Now actions are created by action creators some of the points to be considered in actions are that it must have type property that indicates the type of action being performed they must be defined as a string constant and you can add more properties to it now talking about the action Creator action creators are the functions which create actions and they takes in the message converts it into into system understandable format and returns a formatted action object action creators are the normal functions that return the function and to call this action anywhere in the application we can simply use the dispatch function where we can Define dispatch and then we can Define it to do add to do text as a part of dispatch method so here we can add dispatch after action we have reducers basically actions describe the fact that something happened but they don’t specify how the applic State changes in response so here comes the job of reducers reducers are pure functions which specify how the application State changes in response to an action it is based on the error reduced method where it accepts a call back a reducer and let us get a single value out of multiple values so we can Define reducers as pure functions which specify how the application State changes in response to an action some pointers to be considered for reducers are they do not change the value of the input parameter they determine what sort of update needs to be done based on type of the action and returns new values it Returns the previous state if no work needs to be done the root reducer slices up the state based on the state object keys and passes them to their respective specialized reducers reducers don’t manipulate the original state passed to them but make their own copies and then updates them now let’s understand the reducers with the help of a simple example here we have defined whole function reducer with the arguments initial State and action then we can use Simple switch action type in the case at Todo we are returning the object assigned to State and then here we have a to-do list then in text we are going to work on the action. text and then completed should be false that uh is what we are going to return the state itself so here we are taking help of previous state action and new state as part of reducer component we should avoid the following things inside a reducer that mutating its arguments that we should not change the arguments inside a reducer we should not perform side effects like API calls and routing Transitions and we should not call non-pure functions like date. now or math. random now moving on to the star component of Redux that is store store can be defined as an object which brings all the components to work together it calculates the state changes and then notifies the root red us about it so basically store can hold the application State and provide some helper methods to access the state dispatch actions and register listeners so the entire State object tree of an application is saved in a single store here we can pass the middleware to the store to handle processing of data and to keep a log of various actions which can change the state of the source and all the actions return a new state by the reducers here in the example taken we have created a store from Redux where we can import to-do app from the users that we are going to create and then we are going to use the store component as a part of a stores with a store the data State can be synchronized from the server level to the client layer without much difficulty this makes the development of large applications easier and faster store is responsible for holding applications State allowing access to State via get State method registering listeners via subscribed listener allowing the states to be updated via dispatch action and also it handles unregistering of listeners VI the function returned by subscribe listener now let’s talk about the last component view view is nothing but the thing which is displayed on the screen and in formal terms we can say view displays the data provided by the store as you can see in the picture the store provides the data which is displayed as view on the browser screen smart and dump components together build up the view smart components are the managers who are are in charge of the actions and pass down a function via the props to the dump components and dump components provide information to the smart components if any action is required they receive them as props and use them as call back now let’s understand how the components in Redux are set up first of all we have to get the store ready then we have to set up the communication amongst the components and then we have to prepare the action callbacks let’s understand it with an example so here we have action Creator producers views store provider and root reducer component so these can be called as the various roles involved in setting up the components and then ultimately in the data flow now let’s see how the communication will happen among these components so first step is to get the store ready here in the example the store has been hired and the reducer team has been asked to help the store out so here in the example the store has been hired and the Reger team has been asked to help the store out then in the next step that is setting up the communication between the store and other components we can see the example where the root component says to the provider that this store is hired and now the provider has to set up the network to keep the components updated and here’s the view part so view will get connected to the latest updates to display the user now the final step is to prepare the action callbacks so here the view part has to make it easy for dumb components to understand it has to bind the action Creator and the dispatcher so that the dumb component can just call the call back as we know if something has to be updated as a store is immutable an action has to be triggered which can be done by action. Dispatch method now let’s understand the data flow that is how data will flow among all these components of Redux so Redux architecture is concentrated on a strict unidirectional data flow in an application all the data follows the same life cycle pattern making the logic of your app more predictable and easier to understand it also encourages data normalization to ensure consistency the picture represents the flow diagram of the Redux application which contains all the components which we have discussed now let’s understand the data flow with the help of this example step by step starting from here where the name is John we want to update it with something else so it will start from action Creator start starting with the step one so the action type is name update value is John this is available on The View and to change it an action has to be triggered now the Second Step where the store will get informed by the action store has the current state tree and now it will be passed to the reducer to calculate how the new state Tre should look like so in the third step the reducers which are the pure functions will get the previous state or previous State pre and action as input and will provide the new state now in the fourth step the root reducer will provide the sliced state tree to other reducers in the fifth step the other reducers will copy the sliced data and will update it and it will show the root reducer that how the sliced state tree will look like and in sixth step the store will be updated and then store will inform the provider with the new state tree or the new state which will complete the step seven and step eight and finally in the step nine the view the new state tree will be updated which we can reender as the component tree so I would sum up the entire process in the following brief steps starting with initial step a Redux store is created using a root reducer function the store calls the root reducer once and saves the return value as its initial State when the UI is first rendered UI components access the current state of the Redux store and use that data to decide what to render they also subscribe to any future Store updates so they can know if the state has changed talking about the updates something happens in the app such as a user clicking a button the app code dispatches an action to the Redux store like dispatch and the type could be counter or increment the store runs the reducer function again with the previous state and the current action and saves the return value as a new state the store notifies all parts of the UI that are subscribed that the store has been updated each UI component that needs data from the store checks to see if the parts of the state the niche have changed each component that sees its data has changed forces a reender with the new data so it can update what’s shown on the screen now we will see how to use react with Redux so to install this stable version using npm we can use the command npm install Redux and to yarn we can use the command yarn add Redux react bindings are not included in Redux by default so you need to install them explicitly using the command npm install hyphen hyphen save react hyphen reduct you have to add these dependencies along with Babel react and webpack now I will show you a small demo of using react with Redux so let’s start with a demo and this let’s uh first see the structure of the whole project so we have created these folders actions components containers reducers and the main file index.js so these all are the components which we have seen while understanding this reactjs and Redux so starting with this main file so index.js is always the first or the main file of a react Redux application of project so in this we are using a special react Redux component called provider as you can see here so this one is the special component and it makes the store available to all the container components in the application without passing it explicitly so we need to use it once when to render the root component so here you can see we are rendering the root component with the name app so here we are using provider so we have to use it once while rendering the root component now we have created this file by importing all the dependencies required you can see here with the help of import statement we are importing all the dependencies which are required it could be like Redux react Redux or the components or the reducers and all the these things now as you can see here all the dependencies react react Dom and here this react Dom that is actually the data object model which you would have learned in JavaScript so in this file we are calling the utility called as provider to call Root component and now let’s start with the components so here you can see the folder components so these all are the different components which we have created so these components could be presentational components as well as container components so most of the time we use presentational components but sometimes we generate container components as well to connect to the redu store so first of all we’ll see the presentational components so here we have to-do list.js too. JS link doj foo.js and app.js and here this app.js is the root component okay so starting with the to-do list.js so this Todo list.js component or the file contains the to-do list which is showing the visible todos okay and basically these todos are the arrays as you can see here these todos are nothing but the arrays which have been created using three properties you can see here ID completed and text and here on click you can see here on click is an event or a function which is taking ID okay here is taking ID as a number which is a call back to invoke when a to-do is clicked now talking about the other file that is too. JS here it shows a single to-do item here is a property you can see here property types okay so it has a property type which has the event on click and completed and text which shows the completed todos now we have one more component that is link. CHS so it has a link and it will show all the completed todos now then we have the footer. JS here you can see they have different links which are used for the filter as you can see with the help of filter link it allows the user to change the currently visible toos when we will see the output of this application then we will see how we can change the to-do list items with the help of this filter link now talking about our root component that is app.js it is calling all the other JS files which we have created as presentational components you can see here like this add to-do visible to-do list and footer so you can see this footer is also one of the presentational component over here so it is calling this as well and you can see these visible to-do list and add to-do all these are the container components so this root component will call both the components presentational as well as container so as you can see here import as well as the export method okay so initially we have imported presentational component like footer and the container components like add too and visible Todo list now you can see here when you will just over your mouse over here you can see from where these components are coming so you can see from the SRC folder and the container folder we are getting this visible to-do list it is a container component and here for footer you can see it is coming from the components folder this foo.js so this is a presentational component now here we know we require the container components to connect presentational components to Redux so let’s see the container components now here inside the container folder we can see the container components present so these are the visible to-do list.js filter link. JS and add too. JS so starting with the visible to-do list.js which we have created here you can see this file is required by too. JS file which is a presentational component so here we have too. Js which is a presentational component it will require this container component that is visible to-do list.js this is the basic idea and it helps to subscribe to the Redux store wherein we have map state to props here you can see this map state to props which is a special function available in this import connect from react Redux here you can see in this connect function this map state two props is present so it is a special function which will help to subscribe to the Redux store now one thing to pay attention is to import connect function here as you can see while importing we have imported a connect function as well from react and Redux Library what it does is it provides the optimization which avoids unnecessary reentering of the application here we are calling the function with the help of get visible to-do utility so we have a switch case in which we have three cases all these three cases are actually the ACs which are show all then show completed and then we have show activ these are actually the todos the action is to show all to-do items then show all completed to-do items and then show all the active to-do items now talking about this filter link. JS here it is a container component which is rendering the links by dispatching an action as you can see over here with the help of dis map dispatch to props utility which we have got from this connect function which we have imported from react Redux Library it is rendering the links by dispatching the action and now talking about this add too. JS here this is returning the HTML part of the application as you can see here we have input value we have the button submit button so when we will see the output there you can see the HTML part which will be visible on the screen so that part comes from this add too. JS file which is actually one of the container components now talking about the actions now you can see here the actions here action is also one of the major component of our Redux application so here in this actions index.js the actions are add too then set visibility filter and toggle to- do now let’s talk about the reducers after actions we’ll move to the reducers and in the reducers we have different reducers present over here index.js too. Js too. spc. Js and visibility filter now in this index.js we are making use of combined reducers utility and we are combining all the other reducers present as we have seen in the example earlier that we have a reducers team where multiple reducers are the part of that team and they together work so here with the help of this combined reducers utility which we have imported from this Redux library with the help of import statement we are combining in the other reducer functions now as we know these reducers are basically the pure functions so other reducers as you can see over here these reducers are nothing but the pure functions which are returning something based on the action so here you can see they are taking the action with the help of the ID and then they are returning something with the help of the case so they are returning the states as we have understood earlier from the examples and we will make use of of all these reducers here by combining them now let’s talk about the output of this application I hope this structure of our Redux application is clear to you all you can create any of the applications on Redux and now talking about the output so here in the output you can see we have a text box and then the submit button and the other buttons also we will see how they will be used now the basic idea of this application is to create a Todo list okay so here we will add some items which will be treated as the items of to-do list so we can add multiple items in this to-do list and then we can categorize them with the help of clicking on those items that whether they are active or they are completed right now we don’t have any item in this list so let’s insert something so for example we are entering to subscribe the adura channel so when we will click on ADD to-do this item has been added in the to-do list for example we can insert like the video one more and for example we’ll write like writing so all these three items I have entered in this to-do list when we have clicked on all so we can see all the items of to-do list when we will click on the active so we have all the active to-do list items and in completed we have nothing because we have not completed any of these to complete it we’ll just click on any of these so to subscribe I have just clicked on it so this item has been completed now when we will see in active items we have only two and in completed we have the one which we have already completed by clicking on it so this was the output for this application which we have [Music] created so the first factor that we’re going to talk about is the application types or the usage react is used to develop web applications whereas react native is used for mobile application development some examples of web applications created using react are Facebook Netflix New York Times Yahoo mail Etc on the other hand react native is used in mobile applications such as Instagram Facebook ads manager Bloomberg Airbnb Uber Eats Etc setup and bundling react native is a framework of JavaScript and it comes with all the essentials that you will need to set up and for the development of your application react on the hand is just a library of JavaScript therefore when you use react you will need various other tools for setup and development live reload live reload or hot reload as mentioned earlier is a feature that allows you to code as well as see the modifications in your application simultaneously react native supports live reload whereas react does not template rendering both react and react native use jsx for the development of views or the templates but react is much better better when it comes to styling your application’s UI using CSS react native on the other hand makes use of native platform apis learning curve even though react is not very difficult to learn react native is much easier this is because you can make use of readymade components and react native while for react you will have to quote them yourself so we’ve done a head-to-head comparison between react and react native the answer to which one is better among the two depends on the type project that you’re creating if you are focusing on creating the UI for a web application then react is what you need but if your project is going to be a mobile application then you can go with react [Music] native angular was developed by Google and its first release dates back to 2010 the first version of angular was also known as angularjs on the other hand react was developed by Facebook in the year 20 13 so coming towards the architecture of these Frameworks angular and react both are component based Frameworks but angular makes use of typescript and HTML whereas react which is a user interface Library makes use of JavaScript and jsx jsx is nothing but a syntax extension for JavaScript the latest version of angular that is angular 9 was released on the 7th of February 2020 one of the core features of this major release is the angular IV to know more about the angular IV you can check out the angular 9 video and blog from Eda whose link is mentioned in the description box below talking about react the latest major version of react is react version 16 the rendering process angular performs client side rendering however it can be rendered on the server side as well using nodejs on the other hand rendering is done on the server side in case of react websites built using these Frameworks YouTube as we all know is the world’s largest video sharing platform owned by Google and this is built on angular another very popular online payments application website PayPal also runs on angular other popular websites that use angular are Walmart which is a multinational retail Corporation and gmail which as we all know is an email service platform I’m sure after listening to this many of you would have felt wow angular is amazing but let me tell you guys that react is nowhere behind Facebook is the developer of react and yes Facebook makes use of react as well other popular applications such as Instagram which is a photos sharing platform and WhatsApp which is a crossplatform messaging app Airbnb where you can book your stairs for your vacation are also built on react so moving on towards the licensing of these two Frameworks both angular 9 and react 16 come under the MIT license MIT or the Massachusetts Institute of of Technology license is an open-source license sometimes it’s also called as the BSD style license and it has minimal software redistribution requirements the DM or the document object model angular makes use of real DM while react uses virtual dor the real dor updates the entire tree structure for HTML tags it does not make much difference in a simple application but if you’re dealing with a large amount of data requests on the same page it affects the performance as well as the user experience hence real dorm actually offers low performance with complex and dynamic applications at times real domor becomes extremely difficult to handle because the whole tree data structure is updated even if a minor change has been made virtual dor on the other hand has its components attached this gives the comfort of navigation within a website virtual Dom is also a node tree that lists out elements and their attributes as objects reacts vender function creates a node tree out of the react components then it Updates this tree in response to the mutations in the data model caused by various actions done either by the user or by the system virtual dor is not browser specific and it is lightweight it is provided in react package for free and eliminates the issues of slow performance of real dor having said this I’m sure you would have understood that virtual dor is better than real dor data binding angular uses two-way data binding event binding and property binding in event data binding angular allows you to bind events along with the methods property binding of angular will allow you to pass data from the component class and set the value to given element at the user end property binding also allows you to control elements property two-way data binding is a very important feature of angular with this angular allows you to make changes from the views to the models and from the models to the Views react unlike angular allows one-way data binding here the UI elements can be changed only after changing the model State the developers however cannot alter the UI elements without updating the corresponding models a great advantage of using the one-way data binding is that throughout the application the data flows in a single Direction which gives you better control over it this makes our application more flexible and leads to increased efficiency so talking about the latest features of angular 9 and react 16 angular 9 has a number of new features which are compilation of application with IV is default in angular 9 your angular 9 application is compiled ahead of time this means the angular’s aot compiler will compile all the HTML and typescript present in your code into JavaScript before your browser downloads and runs it this conversion takes place during the buildt process itself and it also also includes type checking angular 9 requires typescript 3.7 any lower versions are not supported TS lip or the typescript runtime library has also been made a pure dependency rather than a direct one earlier this library was installed automatically but now you will have to explicitly add this using npn or Yan react version 16 allows you to build great user experience models with concurrent mode and suspense concurrent mode is a feature that helps in binding apps faster with great user experiences that can help developers achieve their goals suspense is also a powerful tool for carefully organizing An Elegant loading sequence with a few well-defined states that progressively reveal the content the next very important feature is that react allows you to easily create Dynamic web applications and mobile applications react also provides support for custom Dom attributes instead of ignoring unrecognized HTML and SVG attributes react will now pass them through to the Dome this has the added benefit of allowing us to get rid of most of react’s attribute white list and it helps in reduction of the size of the application react as I’ve already mentioned earlier has a single way data flow that offers a better and streamlined data overview in react version 16 there is an increase in productivity that helps in maintenance of the react project reusing components is the major advantage of react you can start with the usual components like checkbox button Etc once this is done you can move to rer components which is comprised of internal logic which makes it easier to manipulate and Define objects that are used this also ensures the consistency of application and facilitates the code maintenance react version 16 also provides better server side rendering and error handling in this version the server is completely Rewritten and it is very fast it also supports streamlining so you can start sending bytes to the client faster so now moving on towards the next comparison factor which is the speed and productivity talking in terms of angular earlier angular was heavier and a little slower compared to react but now thanks to the angular CLI that the app size of angular has been drastically reduced and offers enhance development experience the angular CLI empar in creating a workspace and Design functioning applications quickly it also empaths in producing components and services with on line commands angular CLI ensures the clean coding feature of typescript before I start the discussion over react let me just tell you what is reduxx rux is an open-source JavaScript library for managing the state of the application it is most commonly used with react for building user interfaces so coming towards react the development speed and productivity slightly get affected due to the involvement of thirdparty libraries like reduxx however react is easier lighter and faster to code when it comes to small projects but for large projects typescript is preferable as it contains numerous features and components therefore angular has an edge over react when it comes to speed and productivity deployment earlier it was complicated to deploy an angular app but now thanks to angular Firebase angular 9 has officially added support to Firebase and angular apps and therefore angular apps are now easier to deploy to Firebase react as I’ve already mentioned earlier is lighter and the size of the application is smaller therefore it becomes easy to deploy the applications created using react these applications are usually deployed using node.js the learning curve learning curve in angular is quite steep as angular provides numerous features options and components for react the learning curve is easy as react is relatively small library and has fewer Concepts to learn when compared to angular and for those who want to learn web development quickly and the project requirement is not too large can go along with react so now coming towards something very important and interesting which is the market Trend the numbers that you see on the screen are taken from Tech Trends website according to Tech Trends there is a close competition in the job market for both these Frameworks however angular holds a slight upper hand overall moving on towards the final factor of comparison which is community support according to the 2019 stack Overflow survey it is clearly shown that react has stopped among the web Frameworks making react the most loved and supported framework by developers however angular is not far behind as it has good developer support by Google both these Frameworks have very good Community Support [Music] now let’s start with the realtime projects which we are going to discuss in this session so as you can see on the screen as well we are going to discuss this pick it up an e-commerce app chatted chit that a chat app fabook a social media app show it off a video sharing app short it out a URL shortener and groov on a music streaming app so let’s just start with this starting with pick it up an e-commerce application I think most of us are very much familiar to e-commerce apps as we know an e-commerce app allows users to add or remove items from a shopping cart view the card and check out using different payment methods so for inspiration you can check out some simpler storefronts like a Shopify storefront as well as massive retailers like Amazon or Walmart now you might have question that how to build this so to build this you can start with creating the app with create react app and add the stripe npm package plus use shopping cart to easily handle payments directly with strip checkout build a node API to handle creating sessions with a strive and then you can deploy it the back end to Heroku front end to ntif fly or you can deploy both on Heroku as well now moving on to the chat app that is chitted and chat that so whether it’s a mobile application like WhatsApp or Viber or a productivity tool like slack or Discord all of these use some kind of realtime chat app it could also be part of a chat widget within a website where customers can directly talk with the site owners now as we know all chat apps allow users to send messages to others in real time react to messages show when they are online or offline for example you can check out slack messenger Discord crisp chat Etc now answering the question of how to build this app so we can start with creating the project with create react app then use a service like Firebase or graphql subscriptions to create and get realtime messages then we can add reactions to message with Emoji using the npm package Emoji M then we can deploy to the web using Firebase tools now moving on to favebook a social media app the app you’re likely most familiar with is a social media application in many ways it’s similar to a chat app but expanded to a larger community of users these users can interact with each other in different ways so a social media app allows users in such a way that they can follow one another to receive their posts add media like images and videos to share with others and interact with post such as liking or commenting on them for inspiration you can check out some real-time examples like Facebook Twitter Instagram Etc now answering the question of how to build this so we can start creating the front end with create react app and creating the back end using a node API then we can use a database like postre SQL or mongodb along with an OM like Prisma of postre SQL or of mongod TV then we can use social authentication with Google Facebook or Twitter using OD zero react or passport.js then finally we can deploy it deploy the backend to Hoku and front end to nlii now let’s move on to show it off a video sharing app a video sharing app is probably the most Broad category as video is used across so many different apps and in many different ways you have video sharing apps like YouTube which allows you to search any browser and look for any video that you could imagine that users have created also Snapchat give us the ability to watch videos from other users that are recorded in a much shorter and more accessible format and they are more oriented around interactions such as likes and Views now let’s see how to build it so we can create the app with create react app and then we can create the back end with node or Express then we can use cloudinary for image and video uploads to the cloudinary API then we can use a database like postre or mongod DB along with an or like Prisma of postra or of mongod then finally we can deploy the back end to Hoku and front end to netlify or we can deploy both on Hoku as well now let’s move on to short it out a URL shortener a URL shortener is basically a simple tool that takes a long URL or the link and turns it into a short URL as we know or you might also not know that URL shortener with support for custom domains allows users to shorten the URLs manage the links and view the click rate statistics for inspiration you can check out some real word examples like cut bitly Etc now let’s see the steps to build this application so create the app with create react app then create the back end with node or Express and you can use a database like postre SQL or mongodb and then we can deploy this to the web using Firebase tools now let’s see groov on a music streaming app just as react applications are perfect for serving video content they are also great for streaming media like music music apps have a similar structure to video sharing apps and may or may not allow users to upload their own music but they do allow users to listen to music like songs comment on songs or even purchase the music even music streaming app can combine elements of a video sharing app as well as an e-commerce application for inspiration you can check out the regular music apps to which many of us switch to almost daily like Spotify SoundCloud Pandora Etc now let me give you an idea how to build it so create the app with create react app then create the back end with node or Express and use cloud for image and video uploads to the cloud API then we can use a databases like post SQL or mongodb and then we can deploy it to the web using Firebase tools now we have discussed about some interesting and full-fledged projects of reactjs now let’s see some small projects which could be a very good good source of enhancing the Practical knowledge of reactjs for beginners there are many example projects created by the react Community now we will see some of the projects that use react without third-party State Management libraries so starting with the calculator it is implementation of the iOS calculator built in react in this you just have to create an UI which can perform mathematical calculations talking about Emoji search react app for searching Emoji so everyone in daily life uses some or the other chatting app where we can do without appropriate emojis or the emoticons so you can just create that emoji search feature using reactjs talking about snapshot a photo gallery with search we can search particular picture with Associated keywords or tags and that’s we need to do in a snapshot using react talking about the image compressor and offline image compressor built with react and browser image compression many of times we need to compress out images to upload somewhere or for storage and every time going for online tools not a good idea right so just create an offline tool with the help of react CHS so these were some small projects which can be created using react JS now let me just summarize it so react GS developers have a bright future ahead as the technology is in Ed in several Industries in fact as opposed to other web development Technologies the react developers are now paying the most with react one can function both on the client side and the server side it facilitates the development of larger applications with its portion and data patterns that improve readability thanks to its versatility increased performance and improved usability features it is an outstanding front-end development program which can be used to create as many many Innovative projects as possible this testing is a very important part of your application because when the application goes live we always have to test our application to make sure it’s working fine because if something got break at the end of the deployment on real time it is very difficult so we have to make sure everything run very good so here software testing is a process to evaluate the functionality of software application with an intent to find whether the developed software met the specific requirement or not and produce of bug free products it’s very important part why should you perform testing cost of fixing the bug is larger if testing is not done at early stage once the application deployed it become very difficult to handle so we have to make sure that we should get it on the early stage only we try to fix that to produce good quality product to make software application defect free to check if the behavior of application is same so the testing also do one more thing that testing help us to verify that the thing we expect is same as it’s there or not to check if the behavior of application is same in development and production environment the type of testing unit testing functional testing and integration testing unit testing unit testing is used to test a small piece of independent code unconcerned with how they are wrapped in your application to prevent regression easy to pinpoint and fix the problem if take longer to execute it likely the code under test is much more complex it should be popular tool to perform react testing is just an enzyme so basically unit testing is more like the way the piece of a code that you right you want to test that code is basically come under your unit testing functional tests are made against combination of many units they use any number of external object or system like database UI security as it testing that how as a product is behaving take longer time to execute the unit test functional test represent major release whereas unit test represent only minor change due to which they’re expected to change less often than a unit test when user entered username and a password and click on send that user will be logged in we can easily see that this function group will compromise for many unit test one for validating username and one for handling a button and so on and an integ testing we ensure system application working correctly it can execute only with the realistic involvment like real database server and other system which like to Target production envirment it is used in case you need to test separate system like database and application it is lower than test say other test and is complex to write a functional test May successful test and ability to idle system to open help dialog box but with integration testing with a new browser or other runtime it found that expected functionality is not achieved test application using zest and enzyme so what is zest zest is a fast testing framework it act as a test Runner assert library and moing library and whereas enzyme is a JavaScript test utility for react that make it easier to assert manipulate and derse your react component output so enzyme provide additional utility methods for rendering a component finding element and interacting with element so basically the component testing or the snapshot testing the one we are talking about is actually achieve using enzyme also on the other side if I talk about create react application setup come with bundle with zist generally what happen when we start writing a test cases we look for a testing but basically your react script package that you have created or the sca folding that you have created is actually come with the zest package inbuilt so you don’t have to install a zest but apart from that we have to install certain other things so now we have to a test with the say snapshot integration with reducer so let’s perform that this is our application that we are working in the Redux on this application I’m going to do some testing first of all I’ll open that in vs code let’s go there now particularly in the vs code so I’ll open our folder and we have to install certain packages for this although as we know zest is by default in built but apart from zest we’ll install certain packages so first of all let me open our folder our application is already running so I’ll stop that and let me install some package there with my command prom I’ll open that I’ll stop it manually and first of all you have to install npmi react test renderer and we need enzyme adapter react so I’ll write enzyme adapter react 16 apart from that as zest is by default there we just need one more enzyme so we need three package one is enzyme one is enzyme adapter react 16 and one is react test render so we install that now while it’s installing we’ll proceed with our next part now it install so we can go back to our application here whenever we have WR any test case so in the SRC folder we have one test folder I’ll do one thing I’ll delete this test folder and write a fresh test folder for us and the test folder should be name as underscore uncore testore uncore now here first of all let’s do a oneof a component testing so if we go back to our component we have one footer component let’s test this component we’ll verify that is that component is as expected or not what we’ll do we’ll make a one Json tree for that and then with that Json tree we’re going to use it it should be a part of our test folder component. test.js so remember one thing your file name should always add with means have test between that and see the color difference also there because it detected that’s a test code now you have to import react here import react from react then you have to import footer first of all from dot slash at least should be do do slash it’s a twofold route component slash footer then we’ll import create that is coming from react test renderer now what we’ll do is we’ll let have one describe keyword so we’ll describe what this test Cas is all about I’ll say it’s a snapshot test for footer now after that we’ll call that function Arrow curly braces we WR test it should be test and we’ll write testing footer anything you can say here it’s a name by which we test what this test case all about after that bracket Arrow curly braces we’ll say let tree equal to create so create footer we’ll make our one Json of footer then after that what is expectation my expectation is 3.2 Json to match snapshot if it match snapshot test case pass else test case fail to match snapshot like this now how to run it just go back to a command prompt and simple run a command npm run test if the test case pass it will show you pass else it fail if the test case pass it is see automatically pick that now spelling mistake is there see it automatically able to pick my test file now it’s running test case pass and your snapshot created in case if I go back and make change in a footer say urea n anything now the test case will fail because it’s not matching the required criteria if I go back and make it back it will work suppose your requirement is that suppose requirement got changed now I want to update my test case because it’s once created it keep on failing so what you can do is as you have this test you can add the update test like this test update upate react script test and update snapshot the second way that you can do now here I’ll add one more test case I’ll say one we did for our component test now we’ll do reducer so I’ll pick that test case and I’ll walk you through how exactly it work now I have a more test for reducer in this I import reducer first of all see what reducer is returning we have to run a test case according to that right now my reducer is returning article and gallery and I test case expectation is same it’s say initial State should be article and gallery later on when we actually pass that particular I’ll say action it should return array so how exactly we can do that so this is where are two test case One initial State one when we pass the action if I go back and I run this see this time three test case and all three pass as it returning me object initially after calling action we got array so now we’re going to talk about maintaining code using G see what happen when n number of developer are working in the application everybody have to sync their code because it’s not possible like one day we give one folder to someone and then they will update that folder they give us back it’s not possible the reason for that is till what extent you keep on doing like this you always have to work in the way that you always upload the code somewhere and those who need the code they will download the code and the code should be keep on in syn now to achieve this functionality we use the GitHub so with the GitHub it become in the way that we can share our code very easily so Version Control is one that record changes for document computer program large website and other collection of information over time it allow multiple user to manage multiple revision of same unit of information it is used to maintain the record of different versions of code the most popular tool used as Version Control control is git why should we use git git is a open source distribution control system for tracking change in source code during software developer snapshot get change made to file rather than itself that mean if file is not changed it is not stored again distribution every user have his own copy which store data locally basically what happen we have a data locally and from there we push fast operation almost every operation on a gate is local hence the speed off by get is lightning fast compared to other tools Branch handling every collaborator work directly in the separate Branch basically if I have something to push I’ll push in my own separate Branch rust nearly every task in get is recorded and hence hard to lose any data the git workflow is like that use git flow to manage your project efficiently work with set of guidelines increase G consistency and popularity if I talk about one by one that Repository is a server where all the collaborator upload change made to the file then local repositor is a copy of database the user all the data file locally through push then working copy is a space where user active directory the user modify existing file and create new file in the space then staging area is a place where all the modified file are marked to be committed our place commit command commit all the file in the staging area to local Repository and push command move all the data in the local repository to remote repository when we do fetch fetch collect the change in remote repository and copy them to Local repository whereas a pull pull the latest change in the code so let me show you how exactly we can push pull the code in the GitHub now for doing that what we’ll do is so let’s go here so this is my GitHub if I want to make any new repository where I can push the code what I’ll do is I’ll go here click on the icon and say Eda like that after that I’ll create one repo now one repository by name of edria created it give me this five commands so now what I’ll do is on my local system I’ll make one folder from where I want to push any code suppose it’s my local system it don’t have anything suppose I’ll take few files here three files I pick I’ll move these three files here now I want to push for a Windows system you need to have a g bash which is already there in this machine right click G bash here we write one by one command the very first command is git in it basically we initialize the git in this folder sorry let me minimize it first of all we minimize the code in this folder like say I’ll say git in it this will initialize the git in this folder I say your hidden folder will be created once you do like that your hidden folder will be created in the gate so let me actually close this one and if I go to view know and I say hidden files item see one get folder created right then you have to add all the code a get add then you write get commit it will commit all the code in a local repository write some command so it say that you’re pushing it first time so you have to set your Global username and password so how we’ll do is we’ll say get config the very first time you’re doing from system you do like this get config hyphen hyphen Global we’ll say user . email so I’ll add my email ID here you have to give the email ID by which you have signed up on the G I’ll add that email ID here it’s wrong email id id you will not take it then then I write here my username of this that is aash developer get config minus minus Global and then I have to say user.name and that is Akash developer like this and now it’s set now you try to commit the code it say still something is missing although we have already done that so it’s actually helped to set a global username first of all let make sure we’ll say get config Hy Global user. email now it is done and then user.name now see it’s committed after that in whichever Rao you want to push you have to pick that path of the trpo like this so I’ll go back and particularly paste it and enter at that and we’ll say get push minus U origin Master like that now this will push the code to this repo tomorrow if anything new want to push just three command get add get commit and get push ask my username and a password I’ll enter that so guys means first time you push like this next time when you want to push you just write get add get commit and get push that’s it now it’s done so see it’s pushing that code if you go back to get your code is pushed next time also get add get commit get push now suppose I open any file and some edit there I write here aast developer or I write something different say developer funnel like that anything I can write here now once I write and I commit the code so suppose some other developer already pushed some code there now what you have to do in your G you will write get pull so the latest commit what whoever made is pulled see creating a remote repository we have already seen how exactly we add the code to the G so we already in the last demo we have created that repo we have given a name and we created that now to push the code we need to have our get bash after that we did get in it then we config that after that we added the remote where you want to push and then we committed that code once it commit it goes to the master Branch after that that suppose if I have to take some different branches like so remove the code we’ll say get RM and the file name get cache or the error showed up if you try to delete the stage file you can force delete by adding minus F to that I’ll show one more thing here suppose I want the two developer are working we can make a branch also we’ll say get checkout minus B checkout now what this will do it make an separate Branch for that I’ll say new feature any name I can give like this now if I add add some file in the folder suppose I’ll create one new file in the folder random file now when I push this s I’ll say get add get commit then get push in that Branch get push minus U origin and the branch name that is new feature that Branch name enter wrong and plus get command was wrong so I have to correct that both the things now this time it’s going to push in separate branch and see on the git we get something in terms of like pull request so what we do in real time we say compare pull request if everything’s look good we can add the reviewer and create that once you read the pull request your reviewer will review the code if they find everything fine they merch so what happened once they confirm merch your both the branches got merch but you’ll see two Branch [Music] here so starting with answering who is a react JS developer reactjs developers design and Implement user interface components for JavaScript based web and mobile applications using the react open-source Library ecosystem these skilled front-end developers are involved in all stages of interface component design from conception to final testing from conception to testing a topnotch react developer can help build interactive components for websites or web applications using the react development Concepts today more and more Enterprises benefit from reactjs a testament to its bouring popularity in software development some of the high traffic websites that use react are Instagram Uber Facebook Twitter Reddit Etc along with the upswing in react usage is the surge in demand for a reactjs developer a highly skilled react developer is involved in the entire stages in the development and maintenance of user interface components a react developer is responsible for Designing and implementing UI components for JavaScript based web applications and mobile applications with the use of open-source Library infrastructure these developers are a part of the entire process starting from conception to the major testing process and follow popular reacts workflows like flux and Redux reactjs developers are front-end developers who build modern-day UI components to improvise applications performance they leverage their knowledge about JavaScript HTML CSS and work closely with testers designers web designers and project managers to create a robust and effective application so I can sum up as reactjs developers are also known as front-end developers who design and Implement user interface components for JavaScript based web and mobile applications using the react open-source Library ecosystem now moving ahead I’m going to discuss the job opportunities for a react GS developer there are thousands of jobs in the world which demand reactjs skills talking about the numbers there are more than 43,000 jobs available on LinkedIn alone in India for react as compared to 2019 there has been 184% of increase in the openings for react GS developers in the year 2020 according to India Today a quest report States after covid-19 that is in 2021 reactjs developer is one of the top digital skilled jobs in demand this quite a huge number of job opportunities makes react one of the skills most of the application developers want to learn and secure a good job moving ahead let me discuss the salary trends of a reactjs developer of course of course salary is important today react has the best pay scale on most of the job suggesting websites like LinkedIn glass store pay scale Etc reactjs developers salary depends on multiple factors like years of experience different roles held over time level of expertise special skills training and certifications and also the geographic locations the average salary for a reactjs developer in India is 79,81 92340 now as I’ve told the average salary for a reactj developer in India is [Music] 79,80 K for frontend developer or engineer the average salary of 650 4K for software engineer and the average salary of 1 million for senior software engineer now moving ahead let me show you the job description which have been posted on different job suggesting portals by top organizations so first for example we have Tech Mahindra the designation is react developer and the locations are Bengaluru Hyderabad and Chennai in their job description they have mentioned the skills required for the candidate it includes btech is a must mte or MCA with relevant experience so they are talking about the graduation and the degree which is required talking about the react skills so as you can see they need a react developer with front-end technology with Redux or d3.js experience they need a candidate which has strong Proficiency in JavaScript including Dom manipulation and the JavaScript object model the candidate should have thorough understanding of react GS and its core principles and experience with popular react GS workflows like flux or ruxx the candidate should be familiar with newer specifications of ecma script which are known as like es6 es7 es10 Etc and restful apis the candidate should be familiar with modern frontend built pipelines and tools and should have the experience with common frontend development tools such as Babel webpack npm Etc the candidate should have the ability to understand business requirements and translate them into technical requirements and familiarity with code versioning tools such as git SVN Mercurial and similar and the candidate should have a knack for benchmarking and optimization if your skill set is matching to this job description you are good to go now let’s see one more job description from EX censure where their designation is reactjs application developer and the location is Bengaluru they require be or preferably certified as technical architect associate they need a full stat developer who has worked with react spring boot or Java microservices the candidate should have an experience of one year on most of react GS bootstrap engin Docker weback J or JavaScript and for backend the candidate should have minimum one year of experience on nodejs python AWS Lambda darker just unit test or P test and the candidate should be a developer with one to two years of experience and a passion for Quality good design and

    clean code so if you are matching this criteria you are good to go for this job so as you have seen some of the job descriptions from different companies now I think you have an idea how to prepare for the jobs for reactjs developer now moving ahead I’m going to discuss the skills required to become a reactjs developer as we have seen in the job descriptions as well so I’m going to explain those skills now starting with basic programming and development skills which include HTML CSS JavaScript reactjs G HTTP protocol and terminal talking about HTML and CS no front-end developer is a stranger to HTML and CSS the ability to work with and craft user interfaces is necessary to every organization at a high level react developers should be able to work with and write centic HTML tags work with and write CSS selectors Implement a CSS reset understand the Box model and how to reset to border box understand Flex box and work with an implement responsive web principles including the proper use of media queries talking about the JavaScript fundamentals including es6 you can’t rock react without a firm understanding of the fundamental concepts that the JavaScript language provides but these es6 skills are also essential which include variables and scoping arrays and objects array methods functions and arrow functions in react every single component you build is a function in one way or another remember that classes are just Constructor functions under the hood regardless of the syntax you are using when building functional components or class components you are using some form of a function and then comes the react this is the main deal you got to learn react and learn it well to become a react developer while learning react you should focus on the topics like routing GSX Etc talking about GSX in react you never really touch HTML proper you work with a syntax extension that is truly one of the most remarkable part of the react ecosystem that is jsx jsx looks so much like HTML you may think of it as HTML flavored JavaScript what’s cool about jsx is that if you know HTML and CSS you intuitively know how to work with jsx jsx is an abstraction on top of the react. create element API one re reason it is vital to the library and why the react team chose to go with it in the first place is that the API would be too cumbersome to use in terms of scaling one potentially could use react. create element to build out an entire application however this wouldn’t be any more efficient than just using HTML proper it may feel at first that we have taken a step backward by adding our markup into our template logic however a few quick minutes with GSX and you will be hooked on the style and now we have new jsx transform as well so you can explore that as well in react you should learn Dom manipulation and event handlers the disc keyword higher order functions and call back functions prototypal inheritance and object creation and the class keyword it doesn’t matter whether you are a front-end developer or a backend developer or even a full stack software engineer you must absolutely know get in 2021 try creating a few repositories on GitHub share your code with other people and learn how to download code from GitHub on your favorite ID git is essential to every developer toolkit for storing projects on Solutions like GitHub bitbucket and gitlab and the skills that should just be part of your day-to-day include tracking changes with ADD commit push and pull branching and merging strategies and handling merge conflicts you should know https protocols like if you want to become a web developer then it’s an absolute must to know HTTP and know it well I’m not asking you to read the specification but you should at least be familiar with common HTTP request methods like get post put patch delete options and how HTTP and https Works in general and you should learn the terminal as well though it’s not mandatory for a frontend developer to learn Linux or terminal I strongly suggest you to get familiar with the terminal configure your shell which includes bash zsh CSH Etc while I’m talking about the skills so you should also be familiar with the build and State Management tools which include node node may be a surprise to many like why would you need to know how to work with node in order to be a client side react developer so the answer is high server load using node with react makes sense when you web application needs handling of multiple requests and maintaining server load balance and react developers need to have a solid understanding of the npm registry this is the place where software developers can go to get software to help them build software sounds funny but truly that’s all the npm is a cloud storage for packages we call dependencies and as you can see on the screen I have mentioned npm or yarn so Yar is a package manager that is built to utilize the npm registry Yan actually optimizes your npm workflows Yar and npm somewhat compete today but the mission of Yar has been to solve a lot of problems that are accepted in the node npm ecosystem npm has been doing everything it can to follow the patterns and practices that yarn presents then comes create react app so it is like a quick start to create a react application you can just install create react app and you can just start with the default application you can add the components in that you can make the changes and you can get your react application ready then comes the web pack and Redux so react has built in State Management and many developers have been bored along the way by discovering the asynchronicity of State updates and how react handles them for that reason and for scalability Redux Wass born Redux is a state management library and more it’s not a framework but an opiniated way of working with data the principles behind Redux are along the lines of functional programming and immutability but it’s not a one- siiz fits all solution mastering the concepts of fundamental react programming prior to diving into Redux is key then comes Redux tongue which is a middleware and comes the flux so flux is also a workflow like Redux so you can choose whether to use Redux or flux depending on the requirement now talking about other utilities like API clients server side rendering tools and testing libraries so in today’s world you will rarely build an isolated GUI that is graphical user interface instead there is more chance that you will build something which communicates with other application using apis like rest and graphql thankfully there are many API clients available for react developers which include rest rest API actually in that we have fetch super agent Etc then we have graphql which includes Apollo relay urql Etc then talking about the server side rendering tools you might be thinking what is the difference between server side rendering and client side rendering let’s clear that before talking about the library which supports server side rendering with react well in client side rendering your browser downloads a minimal HTML page it then renders the JavaScript and fills the content into it while in the case of serers side rendering react components are rendered on server and output HTML content is delivered to the client or browser for server side rendering you can learn next.js or after. JS or roll but I suggest learning just next.js should be enough and testing is one of the important skill for react developers which is often overlooked but if you want to stay ahead from your competition then you should focus on learning libraries which will help you in testing for unit testing you can go for just enzyme sonon moocha Ava tape Etc and for end to end testing you can go for selenium web driver cucumber. JS Etc and for integration testing you can go for karma you can learn the library you want but gist and enzyme are recommended and I want to add up one more thing for virtual reality if you are interested in building virtual reality based application then also you have some framework like react 360 which allows you to exciting 360 and VR experiences using react so if you are interested in that area you can further explore react 360 now comes the soft skills so to become a reactjs developer or any software developer be it front end or backend some of the soft skills are always required by the companies which include competence to translate business needs into technical requirements time management project management communication and interpersonal skills capability to write crisp and clear code problem solving and troubleshooting skills creativity and accountability open-minded team player willing to accept feedback and offer suggestions Etc and you should be having willingness to learn modern-day tools and processes as everything updates very quickly in today’s world and then as you can see on the screen I have mentioned UI and ux so as a frontend developer you must be familiar with the UI and the ux part of the application now I’m moving ahead with the road map to become a react GS developer so to become a reactjs developer you should follow a road map in which you should be familiar with the programming and in programming the skills which I’ve already mentioned you should learn those and then comes a reactjs which is the basic or the main thing which you should be familiar with then you should be completing some of the projects and you should be familiar with tools and utilities which are supporting reactjs and you must have graduation degree and accordingly you can go for the certifications as well which are mentioned in the job description in the particular company for which you are going to apply and also if you are not a fresher you should have the relevant experience as well and to to become a reactjs developer you should set some of the timeline or some deadline within which you will complete all the learning you will attain the required skill set to become a react GS developer the skills which I have mentioned you can go for that so you can attain strong Proficiency in JavaScript object model Dom manipulation and event handlers data structures algorithms jsx and Babel then you can go for understanding reactjs and it’s Main fundamentals like jsx virtual Tom component life cycle Etc you should be proceeding experience with reactjs workflows like flux Redux create react app data structure libraries Etc you should understand the restful apis or graphql HTML CSS es6 code versioning tools like git SVN Etc then popular frontend development tools cicd tools devops performance testing Frameworks like moocha just then you can go for node plus npm and you should have preferred degree in computer science information technology or similar and to help you out to attain all these skills in a proper manner I have some suggestions like you can go for eda’s reactjs certification training course so in this training course you will be trained to build efficient react applications by mastering the concept CS of react Redux and react native as well in this react course you will learn how to build simple components and integrate them into more complex design components and after completing this react online training you will be able to build the applications using react Concepts such as jsx Redux asynchronous programming using Redux Saga middleware fetch data using graph ql perform testing using chest successively deploy applications using ngx and Docker plus build mobile applications using react native and also you can go for react documentation whenever you have any doubt or whenever you are stucking somewhere and you can go for GitHub there so many projects are available which you can clone or take help to build your own and if you have any doubts for which you need some answers you can go for GitHub as well now moving ahead let me discuss the roles and responsibilities of a reactjs developer a skilled react developer makes it painless to create high quality web applications with elegant uis using the react Library reactjs developers bridge the gap between the visual aspect and the server s side component they take a proactive role in streamlining the look and functionality of the applications as an efficient reactjs developer he or she is supposed to perform certain defined roles and follow respons responsibilities to get the best of results here are the major ones that any reactjs developer is supposed to follow Leverage The inbuilt react toolkit create data visualization tools libraries and reusable code for prospects integrate designs and wireframes within the application code monitor interaction of users and convert them into insightful information write application interface code with JavaScript enhance application performance with constant monitoring translate wireframes and design into good quality code optimize components to work seamlessly across different browsers and devices good understanding of CSS libraries git Sigma Adobe XT Etc proper user information authentication and develop responsive web- based UI and if I talk about non-technical roles and responsibilities so it includes constant interaction with other developer teams and design team to discuss UI ideas a thorough review of applications needs and interfacing elements and follow proper documentation for changes in application and further updates now let me discuss why is reactjs in demand reactjs being a multi-layered library has been a key Delight for developers and organizations alike reactjs developers Have Been instrumental in assisting business owners to to focus on their Core Business areas without having to bother about other it related activities this has helped big time in enhancing client satisfaction some of the features of reactjs which have increased the demand of reactjs are flexibility reusability strong documentation and Community Support fast rendering single page loading and easy debugging so when I talk about flexibility it is especially visible when it comes to the use of react for web development when we talk about react’s flexibility we refer to the libraries innate modularity as we know react’s architecture allows bundling frontend code into custom components this providing a solid foundation for the overall development process optimization reactjs allows you to write clean modular code breaking the project into separate components as a result when code is modular it gets easy to maintain and scale react is super flexible in the sense that it can be integrated with other third-party libraries and MVC Frameworks you can choose to create a react project from scratch or gradually introduce react to your existing code base and when I say reusability react doesn’t require big lines of codes to program an application in react we say that everything is a component a user writes small codes called components and combines them to form another component simply any app made with react is a tree of component so react follows right once and use it anywhere principle then comes strong documentation and Community Support being an open source Library react has what it takes to keep attracting more and more New Comers to its Community which makes it only stronger over time as of today react is one of the five top rated repositories on giab with over 170k stars and over 5 million applications publicly admitting to using it react has a rich ecosystem to benefit from or contribute to besides finding one’s way around all this information won’t be a big challenge as the react documentation can be easily found on the official website the community is active so you can get rapid feedback or response to your inquiry once you feel stuck currently on stack Overflow there are over 14 million questions tagged react GS that have at least one accepted answer so once you encounter a problem chances are someone has already had same problem and there is a solution to it so that you will only have to copy paste it from the corresponding discussion thread talking about the fast rendering so react is a client side JavaScript library that uses server side rendering react’s virtual Dom is basically the prime cause of faster rendering and the better performance of react apps and this react virtual D serves as a layer between how things are supposed to look and the actual processes happening to render all of those things onto the page and the single page loading so due to the single page loading with the help of virtual term this fast rendering is achieved and then we can talk about the easy debugging in react props and estate are the bread crumbs like when something goes wrong it is important that we have breadcrumbs to trace the mistake take to its source in the code base and if you see something wrong on the screen you can open react div tools and find the component responsible for rendering and then see if the props and states are correct if they are you know that the problem is in the component’s render function or some function that is called by render function the problem is isolated if the state is wrong you know that the problem is caused by one of the set State calls in this file this two is relatively simple to locate and fix because usually there are only a few set ofate calls in a single file and react results in not only easy debuggable code but also highly testable applications with the help of chest or enzyme Etc now let me discuss the future of react GS developers reactjs developers surely have a promising future since reactjs is showing no chances of turning back as you must have seen the requirement for reactjs developers on different jobs suggesting portals and on LinkedIn itself we have 43,000 and more jobs for reactjs developers we have 170k stars on GitHub so many requests for the applications and more than 90,000 live websites are using reactjs and a lot of organizations have started migrating to react so they definitely need more and more RS developers now as compared to other peer comp competitors react CH developers are being paid heavily and are in demand Facebook and the entire Community have been trying hard to keep enhancing the effectiveness and speed of reactjs hence it is imperative that reactjs will keep fighting the competition hard and come out as a winner newer updates and ways of rendering are expected soon the way it is growing the demand for reactjs developers is exponentially higher to sum up I would say the word is unquestionably changing in Rapid and dramatic ways and the demand for reactjs developers is going to keep increasing for sure now after discussing a lot of things and addressing a lot of questions I hope you have got the idea how to become a reactjs developer from where to start how to start what skills are required why those skills are required Etc all these questions have been addressed [Music] I will discuss the questions on four topics of react which are being frequently Asked in react interviews the topics covered today are react GS Basics or the general react then reactjs components then we have reactjs Redux and reactjs router now starting with the general react questions so the first or the basic question on react is what is reactjs to answer this question I would say reactjs is an open-source frontend JavaScript library which is used to build user interfaces and handle view layer for web and mobile applications it follows a component based approach the react package contains only the functionality necessary to Define react components and it is typically used together with a react renderer like react Dom for the web or react native for the native environment now here when I talk about component based approach so everything in reactjs is a component so what happens is these components can be reused they can be placed wherever required so we can just write it once and use it anywhere and any time now even though react was open sourced only in 2015 it has one of the largest communities supporting it moving to the second question that is what are the features of reactjs to answer this question I would say the major three features of reacts JS because of which reactjs is known are virtual Dom server side rendering and unidirectional data flow or data binding it’s talking about the virtual Dom that is actually the virtual data object model a virtual Dom is a lightweight JavaScript object which originally is just a copy of the real Dom it is a node tree that lists the elements their attributes and content as objects and their properties reacts render function creates a not tree out of the react components it then updates this tree in response to the mutations in the data model which is caused by various actions done by the user or by the system talking about the serers side rendering when I say serers side rendering which means using a server to generate HTML from JS modules in response to a URL request that’s in contrast to client side rendering which uses the browser to create HTML using the Dom server side rendering with JS or react Works similarly to other server side languages now when I say unit directional data flow data binding so in react data flows in a single direction that is from parent components to child components which helps in data binding and it makes the application and the code predictable and more debuggable moving ahead with the next question which asks list some of the major advantages of react talking about the advantages of react so it increases the application’s performance it can be conveniently used on the client as well as server side because of jsx cod’s readability increases and react is easy to integrate with other Frameworks like meteor angular Etc and using react writing UI test cases becomes extremely easy now let’s move ahead to the next question which asks what are the limitations of react talking about the limitations of react react is just a library not a full-blown framework and its library is very large and takes time to understand it can be a little difficult for the Novis programmers to understand and coding gets a little complex as it uses inline templating and jsx now the next question is what is jsx so jsx is basically shorthand for JavaScript XML this is a type of file used by react which utilizes the expressiveness of JavaScript along with HTML like template syntax this makes the HTML file really easy to understand and this file makes applications robust and boost boost its performance now let’s see the next question which is what do you understand by virtual dor explain its working so as we have discussed in a previous question also about virtual domor a virtual domor is a lightweight JavaScript object which is just the copy of the real Dom it is a notary that lists the elements their attributes and content as objects and their properties react’s render function creates a not Tre out of the react components it then Updates this tree in respon responds to the mutations in the data model which is caused by various actions done by user or by the system and this virtual Dom Works in three simple steps which are whenever any underlying data changes the entire UI is rendered in Virtual Dom representation then the difference between the previous Dom representation and the new one is calculated and once the calculations are done the real Dom will be updated only with the things that have actually changed so here a kind of patch work is done as you can see in the picture also moving ahead with the next question that is differentiate between real Dom and virtual Dom when we compare real Dom and virtual Dom we find the differences like real Dom updates slow while virtual Dom updates faster real Dom can directly update HTML while virtual Dom can’t directly update HTML real Dom creates a new Dom if element updates while virtual Dom updates the GSX if element updates so that’s why real Dom is comparatively slower than the virtual Dom because in real Dom every time any element gets updated a new Dom is created while with react which uses virtual Dom whenever any element gets updated only the js6 part gets updated now the next difference is Dom manipulation is very expensive in real Dom because every time you have to create the new Dom while Dom manipulation in react that is virtual Dom is very easy and real Dom results into too much of memory wastage while virtual Dom results in no memory wastage at all the reason we know because every time new Dom is created whenever any element gets updated while with the help of virtual Dom in react only the GSX part gets updated with the update in any element now moving to the next question which asks why can’t browsers read GSX browsers can only read JavaScript objects but jsx is not a regular JavaScript object thus to enable a browser to read jsx first we need to transform jsx file into a JavaScript object using jsx Transformers like Babel and then pass it to the browser now let’s move ahead with the next question that is what is jsx transform as browsers don’t support GSX the compilers like Babel or typescript are used to transform GSX into regular Javas script object which is understood by the browsers as we have seen in the previous question now jsx transform automatically compiles the jsx source code without having to rely upon the typical compilers with the new transform jsx can be used without importing react and according to the setup its compiled output slightly improves the bundle size as well now let’s see the answer for the next question which is how react syntax changed from es5 to es6 so as you can see on the screen the code snipp it for es5 and es6 so in es5 we use react. create class and which we initialize in a variable for example here we have taken my component but in es6 we just make use of classes and we make use of extend keyword and the syntax is class the name of the component my component or the class my component extends react. component so the major difference between es6 and es5 is in es5 we make use of create class while in es6 we make use of react. component now let’s move ahead with the next question that is how errors are handled in react so talking about the error handling in react the most distinctive and react specific type of error handling is what is known as error boundaries so error boundaries are react components that catch JavaScript errors anywhere in their child component tree log those errors and display a fallback UI instead of the component tree that crashed error boundaries catch errors during rendering in life cycle methods and in Constructors of the whole tree below them now let’s see the next question that is what are the limitations of error boundaries in react so talking about the limitations of error boundaries error boundaries do not catch errors for event handlers asynchronous code that is set a timeout or request anim frame callbacks for server side rendering and errors thrown in the error boundary itself rather than its children now let’s see the next question that is what are the features introduced in es7 so ecma is script 2016 or es7 introduced two new features that are array.prototype do includes function and the second one is exponentiation operator talking about array.prototype do includes function so it checks the array for the value passed as an argument it returns true if the array contains the value otherwise it returns false earlier we needed to use array. prototype. index of function to check if the given array contains an element or not talking about exponentiation operator so ecma script 2016 or es7 introduced the exponentiation operator that is double Aster it has the same purpose as math. power function it Returns the first argument raised to the power of the second argument moving to the next question which asks list some of the features of es10 so this is the latest version of ecma script so the features introduced in es10 include optional cach binding object. from entries array. flat function array. flat map function Dynamic import Global this object now the next question is how is react different from angular so talking about the differences between react and angular we see on the basis of architecture react is only the view of MVC that is model view controller while angular is complete framework for MVC that is model view and controller talking about the rendering so react supports server side rendering while angular supports client side rendering talking about the Dom that is data object model so as we have seen earlier also react uses virtual D and we have seen the advantages of using virtual Dom while angular uses the real Dom talking about the data binding react uses oneway data binding or the unidirectional data flow while angular has two-way data binding or the bir directional data flow talking about the debugging react supports compile time debugging while angular supports runtime debugging and talking about the author or who owns react and angular so react is owned by Facebook while the author of angular is Google with this we have seen some of the frequently asked questions and answers based on General react now moving ahead let’s see the questions based on react GS components so starting with the first question based on reacts components what do you understand from in react everything is a component to answer this question I would say components are the building blocks of a react application UI so everything in react is a component and these components split up the entire UI into small independent and reusable pieces then it renders each of these components independent of each other without affecting the rest of the UI and these components can be JavaScript functions which takes in arbitrary inputs and returns HTML representation now let’s see the next question which asks what is the purpose of render function in react or explain the purp purpose of render function in react to answer this question I would say each react component must have a render function mandatorily it returns a single react element which is the representation of the Native Dom component if more than one HTML element needs to be rendered then they must be grouped together inside one enclosing tag such as form group div Etc this function must be kept pure that is it must return the same result each time it is invoked moving to the next question that is how can you embed two components into one so as you can see on the screen we have one code snippet we have embedded two components with the help of class then the component name or the class name then using the keyword extends and we made the use of react. component with this syntax as you can see on the screen we are embedding two components into one so there are two components the my component and header component moving to the next question that asks what are props in react so Props is basically the Shand for properties in react they are readon components which must be kept pure that is immutable and they are always passed down from the parent to the child components throughout the application a child component can never send a prop back to the parent component and this helps in maintaining the unidirectional data flow or the data binding and are generally used to render the dynamically generated data moving to the next question what is a state in react and how it is used talking about the states so states are the heart of react components states are the source of data and must be kept as simple as possible basically states are the objects which determine components rendering and behavior they are mutable unlike the props and create Dynamic and interactive components and they are accessed via this do state function moving to the next question which is differentiate between State and props so while comparing State and props we find the differences like in state and prop both receive initial value from parent component while in state parent component cannot change value while with the help of prop parent component can change the value and we can set default values inside the components both in state as well as in props in state we can make changes inside the component but with props we cannot make the changes inside the component and we can set initial values for child components in both state as well as in props but changes inside the child components cannot be made in state while in prop we can make the changes inside child components now moving to the next question which asks how can you update state of a component now here you can see a code snippet so basically the answer for this question is we can change the state or we can update the state of a component by making the use of this do set State function and as you can see on the code snippet as well earlier here name was Max and ID was 101 then again in render function we’ll make use of set State basically this do set State function and inside that we can change the value or we can update the state of the component so here we are making the change in the value as you can see over here we are updating it to jaha and id2 triple2 now moving to the next question that is should we update the state directly so to answer this question we should not update the state directly and why we should not update the state directly because if we update the state directly calling the set State function afterward we just replace the update we made made and when we directly update the state it does not change this do state immediately instead it creates a pending State transition and accessing it after calling this method will only return the present value and we will lose control of the state across all the components so that’s why we should not update the state directly moving to the next question that is what is Arrow function and how it is used Arrow functions are more of brief Syntax for writing that function expression they are also called fat Arrow the functions it is symbolized with equal to and greater than symbol now these functions allow to bind the context of the components properly since in es6 Auto binding is not available by default and arrow functions are mostly useful while working with the higher order functions or HFS as you can see in the picture as well without Arrow function and with arrow function without Arrow function we were making use of this do handle change. bind while with aror function we have just made use of this symbol that is equal to and greater than and then we made use of this dot handle on change no need for bind and all now moving to the next question that is how do you reference a Dom element it is a pretty simple question and answer to this question is also very simple and crisp that is an object this do refs that is this do RFS which is found as an instance inside the component can be used to access Dom elements in reactjs now moving to the next question that is what is the use of e do persist function answer of this question is nothing e persist function does nothing because e do persist function was used in event pooling but with react 17 event pooling has been completely removed but this e do persist function is still available on the react event object but now it doesn’t do anything now moving to the next question which asks what do you mean by event pooling as we have seen in the previous question that event pooling has been removed from react 17 but we should know what is event pooling because this question has been frequently Asked in interviews so the synthetic event objects were pulled this means that the synthetic event object would be reused and all properties would be nullified after the event handler has been called now for example you can see the code Snippets available here so earlier when event pulling was supported in react the first snippet as you can see over here this would not work because the event object gets reused but with the help of e do persist function this code works because it prevents react from resetting its properties but this is the case before react 17 now event pooling is not supported by react now moving to the next question what are react hooks so react hooks are functions that let us hook into react State and life cycle features from a functional component so what is this hook into actually these functions let us use the react State and life cycle features from a functional component and react hooks Cann not be used in class components they let us write components without the class now moving to the next question question when and why hooks were introduced in react react hooks were introduced in the 16.8 version of react or react 16.8 earlier functional components were called stateless components and only class components were used for State Management and life cycle methods the need to change a functional component to a class component whenever State Management or life cycle methods were to be used led to the development of hooks now moving to to the next question that is do you know any of the techniques to optimize react app performance so there are many techniques to optimize react app performance but some of them are using use memo function using react. pure component and maintaining state collocation so when I say using use memo function so it is a react hook that is used for caching CPU expensive functions sometimes in a react app a CPU expensive function gets called repeatedly due to reenders of a component which can lead to slow rendering now this use memo function who can be used to cat such functions by using use memo the CPU expensive function gets called only when it is needed talking about using react. pure component so it is a base component class that checks the state and props of a component to know whether the component should be updated instead of using the simple react. component we can use react. pure component to reduce the reenders of a component unnecessarily and ultimately it optimizes the application performance and when I say maintaining state collocation so this is the process of moving the state as close to where we need it as possible sometimes in react application we have a lot of unnecessary States inside the parent component which makes the code less readable and harder to maintain not to forget having many states inside a single comp component leads to unnecessary reenders for the component and it is better to shift states which are less valuable to the parent component to a separate component now moving to the next question what is lazy loading lazy loading is the feature introduced in react version 16.6 which allows for some components to load later than the other components this way we can load the components which are fast like text earlier and the components which load later like images later it is also Al referred to as code splitting and data fetching moving to the next question what is a fragment in react a common pattern in react is for a component to return multiple elements but fragments let us group a list of children without adding extra nodes to the Dom while rendering multiple elements will require a div tag around the content as the render method will only render a single root node inside it at a time so in react 16.2 fragment were introduced and we use them instead of extra div tags and all so as you can see in the code snippet available on the screen in place of using div tag we are just making use of react. fragment and inside this you can see this child a child B CH see these are basically the elements now moving to the next question which asks what is set State function so set State function allows us to change state in a react class component as we have seen in a previous this question we were making use of this do set State function right and the set State function enqs change to the component State and tell react that this component and its children need to be rendered with the updated State this is the primary method you should use to update the UI and set a state does not always update the component immediately instead it may defer the update until later for better performance and the Syntax for this function as we have seen in the previous question also here set State and in the braces we can give the updator or the call back we can pass it as the argument moving to the next question that is what is use State function so the use State function is a react hook that allows to have a state variables in functional components the use State Hook is a special function that takes the initial State as an argument and returns an array of two entries moving to the next question what do you mean by Contex in react so the react context API is a way for a react app to effectively produce Global variables that can be passed around this is the alternative to prop drilling or moving props from grandparent to child to parent and so on a new type of context can be created using react. Create context API and this context API is added in version 16.3 of react that allows one to share state across the entire application or part of it lightly with ease moving to the next question what do you mean by prop drilling so prop drilling can be defined as a process and react application where props are passed from one part of a tree to another by going through other parts that do not need the data but only help in passing it through the tree and it is also known as prop threading now I give it over to Mr asho to take you through the more questions on react components react Redux and react router what are the differences between State full and stateless components this table is showing the differences so stateful components are those which stores information about component State change in memory stess they calculates the internal state of the components stateful components they have authority to change the state as the name suggest stateless components cannot have authority they do not have authority to change the state if I talk about stateful component they contains the knowledge of past current and possible future changes in state stateless components they contains no knowledge of past current and possible future State changes stateless components notifies them about the requirement of the state change then they send down the props to them stateless component if I talk about they receive the props from the stateful components and treat them as call back functions so this table is very important it’s a very general question again asked nowadays in reactjs interviews that what is the difference between stateful and stateless components what are the different phases of react component life cycle in a very interesting one so as we all know that there are four phases so here I’m defecting the three phases and initial phase which are mostly used the updating phase one is the mounting phase and another one is the unmounting phase we can amalgamate the two in one so now it becomes three so initial phase updating phasee and unmounting phase as you can see on the screen every phase is having their own methods which are working in a particular order or this particular priorities so initial phase is having the function as get default props get initial State component will Mount render and component did Mount if I talk about updating phase these are the methods or functions available in the updating phase again it is had render if I talk about the unmounting phase so unmounting phase has a function called components will unmount so these are the various life cycle methods I will say these are called the life cycle methods in reactjs which we need to have so that whatever props or components we are using they gets mounted and unmounted accordingly explain the life cycle methods of react components in detail if I talk about the life cycle methods which we just saw in the previous slide that what are the life cycle methods in react so these are the various methods which we generally use component will mount it gets executed just before the rendering both on client and server side component did Mount it is executed after first render only on the client side the other one is component will receive props it is invoked as soon as the props are received from parent class before another render is called the other method or the life cycle method is should component update it returns true or false value based on certain conditions if you want your component to update return true else return false by default its value is false component will update it is called just before rendering takes place component did update and the other one is component will unmount this is called after the component is unmounted from the top it is used to clear up the memory spaces so all these are the life cycle methods which are used in react JS now what is a event in react events are triggered reactions or I will say actions to specific actions like Mouse over Mouse click key press Etc react events are similar to HTML JavaScript events so for example in this example or in this diagram as you can see this is a bulb is there is an action called switch on if someone clicks on on the bulb is getting on so this is kind of a event which is getting triggered which are reactions to specific actions how we can create events in react JS so as you can see here this is a render function class display extends react. component in es6 class standard of writing the code here I’m using a render function which is returning a TI and on click is the event that is how we can create the events in react CHS this. show click me what are synthetic events in react CH synthetic events are uh the cross browser wrappers around the browser’s native event system they combines the browser Behavior into one API and they’re done to ensure events have consistent properties across different browsers so if we want to have a react JS application running on different browsers we will use synthetic events in react JS what do you understand by reps which are references in react JS so reps stands for references so they are used to return references to a particular element or component returned by render they are basically useful when we need Dom measurements or to add methods to the components list some of the cases when you should use reps so first of all they are used to manage Focus text selection or media playback for triggering imperative animations just like as you can see on the screen if you want to display this kind of Animation imperative animation we will use reps in reactjs and if you want to integrate with third party Dom libraries that is also where we use reps in react JS how do you modularize code in react so we can modelize code uh by using the export and import standard or by using export and import properties we can write the component separately in different files so for one file we will use the export property and for another file we can use the import property that is how you can modelize the reactjs code and as you can see on the screen the two code is snippits for or two files I’ll say for export and import properties how forms are created in react this is again a very basic question questions with interview question with respect to react so HTML form elements maintain their own State and regular Dom and update themselves based on user input in reactjs state is contained in the state property of the component and uh it gets only updated bya set State as we all know so JavaScript function is used for handling the form submission what do you know about controlled and uncontrolled components so as I mentioned earlier components are of two type presentational components and container comp components again there are two other types of components which are controlled and uncontrolled so controlled components are those which do not maintain their own State the state is not maintained in control components data is controlled by parent component not by the child components the control components takes in current value through props and notifies changes via call packs I talk about uncontrolled components they maintain their own State data is controlled by Dom and reps are used to get their current value so if you want to use rest we need to have uncontrolled components now what are H when I say h these are high order components so these are the custom components I will say which we develop while doing programming in reactjs so these are the custom components which wraps another component they accept dynamically provided child components then they do not modify the input component they do not copy any behavior from the input component and I’ll say that these are the pure functions basically they are the custom components which are developed to addon functionality to some other components these are called H’s so what can you do with h h means high order components can uh reuse the code logic and bootst step abstraction using H’s we can render High checking State abstraction manipulations and also we can also do state and props manipulations with h high order components now what are pure components pure components are the simplest fastest components which we can right these are very fast they can replace any component that only has render answers the Simplicity and performance of the application these are the pure components as you can see here there is a code snippet react dom. render H1 hello document. get element by ID content so these are the two parameter which needs to be passed to the render function and this is the simple component I will say simplest component or I can say the pure components which we can write in reactjs and Hance the performance and it I will it is the fastest in react CHS now what is the significance of keys in react chairs or what is the significance of keys in react it is used to identify unique virtual Dom elements with their corresponding data driving the UI so as we all know there is a key value pair combination always in every programming language just like that we have keys and reactj which is used to identify the virtual Dom elements and what are the virtual Dom elements with respect to their driving UI this we can know using keys in react CHS they must be unique number or a string they helps react to optimize rendering by recycling existing Dom elements so instead of rendering with keys react just reorders the element so if you don’t want to reender your UI or if you don’t want to reender your components you can just reorder the elements using keys in react CHS and obviously with all these T the performance of the application gets optimized and highly increased in react ch so that was all about the second section of the react interview question let’s move forward and now I will talk about the interview questions related to react Redux this is a combination of react and Redux technology so what were the major problem with MVC framework see we all know it’s a model view controller so what is the major problem so Dom manipulation is very expensive because MVC framework is completely based on Dom and not on Virtual Dom just like in react CHS is slow and inefficient there is lot of memory wastage in MVC framework because of circular dependency complicated model was created around model and Views so these are some of the drawbacks or problems with MVC framework now flux before Redux there was a technology called flux which was introduced by Facebook so what was flux architectural pattern that enforces unidirectional data flow so on the screen as you can see there is a action then dispatcher store and view so architectural pattern that enforces unidirectional data flow controls derive data and enables communication between multiple components now as you can see there is a central store which has Authority for all the data any update in data must occur here only so store is the central or the heart for all react Redux or flux application it provides stability to the application and it reduces runtime errors what is Redux Redux is one of the hottest Library I will say for frontend development it is very very famous you can also check how much it is famous and its popularity on GitHub sites that it has more number of stars and more number of watches as compared to flux it’s aable state container for JavaScript apps it is mostly used for State Management applications where State needs to be managed uh applications developed with Redux are easy to test and it helps to write applications that behave consistently and can run in different envir en Ms what are the three principles that Redux follows first is a single source of truth that is the store single source of Truth and when I say I’m talking about here the single store there is only one store in a Redux or react Redux application state is read only in Redux the changes are made with pure functions you can make changes only with the pure functions in Redux libraries what do you understand by single source of truth when I say single source of Truth it is the store which I’m talking about in Redux application Redux uses a store for storing all the application State at one place whatever the state happening or state changes happening in a react Redux application it will be notified to store or will happen uh in conjunction with a store so component state is stored in the store and they receive updates from the store itself so whatever the components so these are the various components so the state of all these components will be stored in a single place which is called store and any update needs to happen or needs to be there that will be received from the store itself the single state tree makes it easier because it’s a single state tree makes it easier to keep track of the changes over time and debug or inspect the application what are the various components of Redux first one is the action which is an object that describe what happen happened reducer it is a place to determine how the state will change or I will say the reducers are the pure functions which ISS how it needs to be done as I said action that what needs to be done reducer how it needs to be done is given by the reducers because these are the pure functions store as you saw just now in the previous slide that store is a single source of truth then need to be a single store which is used for State Management of all the components so a state object of the entire application is saved in the store view is to Simply displays the data provided by the store so how the data flows through Redux again a very interesting question that how we should know that how data is flowing through Redux so as you can see here that these are the container components which is passing data as the props they are passing the data to actions action is passing the data to reducer so the input for the store is the reducer and reducer is again giving the data to the provider component or you can say the view part of it so that is how the data Flows In Redux applications how actions are defined in Redux always remember that action should have a type property that indicates the type of action which needs to be performed so type is very important for every action so let’s say in this code is snip it as you can see on the screen there is a function called add to which is taking the input parameter as text is what it is returning is it is a type and this what type of action it is act to do so they must be defined as a string constant and we can add more properties to it that is not a problem with the action you can add as many properties as you want but the most mandatory part or the most important part for an action is it needs to have a type property and actions are created using functions called action creators the other question which we have is what is the role of reducers reducers are the pure functions which specify how the application State changes in response to an action it takes in the previous state and then action and Returns the new state so what is the work of a reducer basically it takes the previous state make the changes and it Returns the new state it determine what sort of update needs to be done based on the type of action and Returns the new values it Returns the previous state if no work needs to be done if there are no changes in the state or if there are no updates of obviously it will return the previous state which it takes as a input and as output it returns a new state with the changed parameters what is the significance of a store in Redux store as we all know now that store is the single source of Truth a JavaScript object holds the application state it maintains the application or I can say it maintains the state tree of the particular application that is the store provides a helper methods to access the state dispatch ction and register listeners with store the data State can be synchronized from the server level to the client CER without much hle and since it’s a single store it’s a single source of truth it’s a single place to maintain the state tree of the application it makes the development of the large application very easy and fast how Redux is different from flux so these are the basic differences between flux and Redux I talk about flux the store contains State and change log has multiple stores flat disconnected stores inlux all the stores are disconnected single turn dispatcher react component subscribed to the store in flux state is mutable so you can change the state in flux if I talk about Redux store and change logic are separate we have a single store in Redux single store with hierarchical reducers you can have multiple reduc ERS in Redux but the store needs to be single in react Redux application so if I talk about the container components they utilize connect and state is immutable this is again very important that the state is immutable in react Redux application what are the advantages of reduct so I’ve list down some of the advantages of Redux predictability maintainability the application will be very fast it will be optimized we have many developer tools the testing and debugging part will be easy and huge open source Community for Redux is available out there on internet and precise organization of course because there is only one store which is maintaining the state complete state of the application so these are some of the advantages of Redux which makes react Redux application very famous and very popular and the next question in react Redux is what is Redux tun so Redux tun is a middleware that lets call Action ction creators that return a function instead of an action object that function receives a stores dispatch method which is then used to dispatch regular synchronous actions inside the body of the function once the asynchronous operations have completed and the tongue can be used to delay the dispatch of an action or to dispatch only if a certain condition is met and basically it sits between action Creator and reducer in the react Redux flow now moving to the last part of the last section of this webinar that is the react router interview questions what is react router it’s a very powerful routing Library I’ll say it helps in adding new screens and flows to the application it keeps the URL in sync with data that is being displayed on the web page and it is a very simple API the react router API are very simple to use why switch keyword is used in react router version 4 the switch keyword is used when you want to display only a single route to be rendered among several defined routs so as you can see here if I want to have multiple defined Roots but I want to display only a single root then I use the switch statement why do we need a router in react so router helps in defining multiple routs inside the router with each route leading to a unique view as you can see on the screen there are multiple react routers for example these are the three router and each router is leading or representing I will say a unique view so that is why we need a router in react list down the advantages of react router so there are various advantage of react router the API is very simple and the API is all about component the API is component based the router apis it can be visualized the single root component no need to manually set history value it has separate packages for web and Native platforms that’s very famous how react router is different from conventional routing of data so again there’s a table of the differences based on the various topics Pages involved each view corresponds to a new file in react router only single HTML page is involved in conventional routing we used to have multiple PES involved in application if I talk about the URL changes in conventional routing HTP request is sent to the server and corresponding HTML page is received in react router only the history attribute is changed this is a very drastic change in the uh request response terminologies if I talk about the look and feel user actually navigates across different pages for each view in conventional routing but for react router user is duped thinking he’s navigating across different pages but it is actually not the case now the next question is why is switch keyword used in react router V5 or version 5 although a div tag is used to encapsulate multiple Roots inside the router the switch keyword is used when we want to display only a single route to be rendered amongst the several defined Roots the switch tab when in use matches the typed URL with the defined roots in sequential order when the first match is found it renders the specified value and thereby bypassing the remaining Roots as we have seen some of the frequently asked questions and answers in react interviews now let’s have a look on the requirements or the skills required to become a reactjs developer so to become a reactjs developer you should have the following skills which include fundamentals of HTML CSS and JavaScript fundamentals of reactjs which includes jsx es6 hooks node plus npm and Redux and with this we come to an end to this react GS full course and if you enjoyed listening to this full course please be kind enough to like it and you can comment on any of your doubts and queries we will reply to them at the earliest do look up for more videos and playlist And subscribe to the ureas YouTube channel to learn more thank you for watching and happy learning

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • React Essentials: Components, State, and Developer Tools

    React Essentials: Components, State, and Developer Tools

    These excerpts detail React development concepts and practices through hands-on challenges. The text introduces core concepts like components, JSX syntax, and rendering. It explains props and state for building reusable, data-driven UIs, including handling complex data like arrays and objects. Various challenges focus on practical skills like styling components, managing events, and fetching data from external APIs. The final segments involve Capstone projects designed to reinforce all concepts, including game building as a method to solidify React skills. The overarching theme is learning React through active participation and iterative problem-solving.

    React Fundamentals Study Guide

    Quiz

    1. How do you typically select the DOM node where React will insert its content?

    You can select a DOM node using standard JavaScript DOM selection methods such as document.getElementById() or document.querySelector(). The selected node serves as the root for the React application.

    2. What does the createRoot method do, and where does it come from?

    The createRoot method creates a root instance that allows React to manage and render content within a specific DOM node. It is imported from react-dom/client.

    3. What does the render method do?

    The render method takes React components or elements (JSX) and displays them inside the specified root DOM node, managed by createRoot.

    4. What is JSX?

    JSX is a syntax extension to JavaScript that allows writing HTML-like structures within JavaScript code. It is transformed into regular JavaScript function calls by tools like Babel.

    5. Why is it important to export components from their respective files?

    Exporting a component allows it to be used in other files within the application. This promotes modularity and code reusability. It can be accomplished using export default or named exports.

    6. What is the difference between a default export and a named export?

    A default export allows you to import a module under any name, while a named export requires you to import a module using its specific name.

    7. What is the purpose of using a build tool like Vite?

    Build tools like Vite streamline the development process by providing features like fast development servers, module bundling, and optimization for production. They handle the complexities of modern JavaScript development, such as JSX transpilation and dependency management.

    8. What is the purpose of React fragments, and what do they look like?

    React fragments allow you to group a list of children without adding extra nodes to the DOM. They are represented by empty tags <></> or the <React.Fragment> component.

    9. What are props in React?

    Props (short for properties) are a mechanism for passing data from a parent component to a child component. They enable components to be dynamic and reusable.

    10. How do you pass a value to a component that is not a string?

    When passing non-string values via props, enclose the value in curly braces. For example: `<Component upvotes={10} isPun={true} />`.

    Essay Questions

    1. Discuss the benefits of using components to build user interfaces, and explain how React facilitates component-based development.
    2. Explain how JSX simplifies the process of writing React user interfaces compared to using vanilla JavaScript. Provide examples to illustrate your points.
    3. Describe the steps involved in setting up a React development environment using Vite. Explain the role of Node.js and npm in this process.
    4. Explain the difference between state and props in React, and why both are important for creating dynamic user interfaces. Provide examples.
    5. Discuss the importance of accessibility in web development, and describe some of the techniques that can be used to make React applications more accessible.

    Glossary

    • DOM (Document Object Model): A programming interface for HTML and XML documents. It represents the page so that programs can change the document structure, style, and content. React uses a virtual DOM to efficiently update the actual DOM.
    • Component: A self-contained, reusable piece of code that represents a part of the user interface. React applications are built by composing components together.
    • JSX: A syntax extension to JavaScript that allows you to write HTML-like code in your JavaScript files.
    • createRoot: A method in React that creates a root object for rendering a React component into a specific DOM node.
    • render: A method used to display React elements or components within a specified DOM node.
    • Module Bundler: A tool that takes JavaScript and its dependencies and packages them into a single file or a set of files for use in a browser.
    • Vite: A fast build tool that serves your code during development and bundles it for production.
    • Node.js: A JavaScript runtime built on Chrome’s V8 JavaScript engine, which allows you to run JavaScript on the server-side.
    • npm (Node Package Manager): A package manager for JavaScript that allows you to easily install and manage dependencies in your projects.
    • Props (Properties): Data passed from a parent component to a child component. Props are read-only from the child component’s perspective.
    • State: Data that is managed within a component. Unlike props, state can be changed by the component itself, triggering a re-render of the component and its children.
    • Event Handler: A function that is called when a specific event occurs (e.g., a button click).
    • Conditional Rendering: A technique used in React to display different content based on certain conditions.
    • Accessibility (a11y): The practice of designing and developing websites that are usable by people with disabilities.
    • aria-label: An HTML attribute used to provide a descriptive label for an element, especially for assistive technologies like screen readers.
    • clsx: A tiny utility for constructing className strings conditionally and concisely.
    • key: A special string attribute you need to include when creating lists of elements. Keys give the elements a stable identity.
    • useEffect: A React Hook that lets you perform side effects in function components. Data fetching, setting up subscriptions, and manually changing the DOM in React components are all examples of side effects.
    • Side Effect: Operations that affect something outside the scope of the current function being executed, such as directly manipulating the DOM, or fetching data from an API.
    • Spread syntax: A modern javascript feature that allows you to copy all or part of an existing array or object into another array or object.
    • Ternary Operator: A Javascript operator that is a shorthand way to write an if…else statement in one line. condition ? expressionIfTrue : expressionIfFalse

    React Fundamentals: A Practical Introduction

    Okay, here’s a briefing document summarizing the main themes and ideas from the provided source:

    Briefing Document: React Fundamentals and Setup

    Overview:

    This document summarizes a lesson focused on introducing the fundamentals of React development, including rendering content to the DOM, working with JSX, setting up a local React development environment using Vite, component creation, styling, props, state and conditional rendering. The lesson employs a hands-on approach, encouraging the learner to actively rewrite and modify code through challenges.

    Main Themes and Ideas:

    • Rendering with React:
    • React uses a “root” to insert its content into the DOM. This is achieved using createRoot from react-dom/client.
    • The render method of the root is then used to display content, which often looks like HTML within JavaScript (JSX).
    • Quote:…up is going to be like the root of our application it’s the one place where react will insert everything so what I need to pass to the create root method is this Dom node and I can get it by doing any regular Dom node selection I can say document. getet element by ID for example and pass in the ID of root and now that I have a so-called root I can call a method on that route called render…
    • Quote: “…I’m going to pass what looks an awful lot like HTML inside of my JavaScript…”
    • JSX Syntax:
    • JSX allows writing HTML-like structures within JavaScript code.
    • It is crucial to use the .jsx extension for files containing JSX so that Vite can compile it correctly.
    • JSX allows developers to lean on a familiar HTML syntax.
    • Quote:…we’re starting to see one of the benefits of using react is we can lean on a familiar syntax in HTML with a couple tweaks here and there that we’ll be discovering as we go through this course…
    • Setting Up a Local React Environment with Vite:
    • Vite is recommended as a fast build tool for React projects.
    • It requires Node.js and npm to be installed. NVM (Node Version Manager) is suggested for easy installation and updates.
    • The command npm create vite@latest is used to scaffold a new React project.
    • Quote:…We’re going to be using the recommended build tool called vit and yes it is pronounced vit that’s French for quick or fast…
    • Components:
    • React applications are built using components.
    • Components can be moved into their own files for better organization and reusability.
    • JSX elements need to be enclosed by a single top level or parent element.
    • Components are exported and imported using export default and import. When using export default, you do not need to surround the component name when importing.
    • Quote:…moving these components into their own files is a really simple task…
    • Styling:
    • The lesson encourages practicing CSS styling to customize the appearance of React applications.
    • Opportunities are given to put design tweaks on the projects and post them in the Scrimba Discord community.
    • Styling can be controlled with CSS files, including font families, padding, colors and flexbox properties.
    • Quote:…I want this to be not only an opportunity to practice playing in the code which is probably why you’re here on scrimba in the first place but also to give you an opportunity to interact with the scrimba community…
    • Props
    • Props are a mechanism for passing data from a parent component to a child component.
    • Props use a similar concept to attributes in HTML.
    • Props can be of any JavaScript data type, not just strings.
    • JSX allows switching into Javascript mode by using curly braces, and in this mode developers can pass props that aren’t of the string data type.
    • Props can have default values, using props.propertyName || defaultValue if a certain condition exists, react gives the developer the control to conditionally render things on the page.
    • State
    • useState is a React hook that allows components to manage and update their own data.
    • The useState hook returns an array with two elements: the current state value and a function to update it (the “setter” function).
    • There are two options for what you can pass into the State Setter function. One, is the new version of state. And two, is a callback function.
    • The callback function receives the old version of state as a parameter.
    • The useState hook allows developers to make the page dynamic.
    • Conditional Rendering
    • Conditional rendering enables displaying different content based on specific conditions.
    • Different ways to apply conditional rendering are: if/else statements, the ternary operator, and the && (AND) operator.
    • The ternary operator can be used in JSX, allowing you to write concise conditional logic inline.
    • React using JavaScript under the hood allows developers to use native Javascript APIs and techniques to help display things on the page.
    • Side Effects and useEffect
    • The useEffect hook is used to perform side effects in functional components (e.g., interacting with the browser API, fetching data).
    • It’s important to clean up side effects when a component unmounts to avoid memory leaks and unexpected behavior.
    • Returning a function from the useEffect callback allows you to specify cleanup logic.
    • Focus on Practice and Learning by Doing:
    • The lesson emphasizes the importance of actively rewriting code and completing challenges to reinforce learning.
    • Taking quizzes like the one included is scientifically proven to improve the developer’s ability to retain information and recall it at a later time.

    Key Quotes Emphasizing Active Learning:

    • I really want you to try this challenge to the best of your abilities before you just simply click the button and move on you’ll hear me say it a million times but you really will just be shorting your own education and your own practice if you decide to take the easy way out…
    • …doing that Discovery process is going to be much better for your long-term memory and your skill building in writing react code then it will be to just skip this Challenge and move forward…
    • …get that muscle memory in get the repetitions in and remember to take breaks along the way throughout this course…

    In Summary:

    The lesson provides a practical introduction to React development, covering essential concepts and techniques. It places a strong emphasis on active learning through coding challenges and encourages the learner to experiment and explore further.

    React Fundamentals: A Concise Overview

    ### What is React and how does it work at a high level?

    React is a JavaScript library for building user interfaces. It allows developers to create dynamic and interactive UIs by breaking them down into reusable components. Under the hood, React manipulates the DOM (Document Object Model) efficiently to update the view when data changes.

    ### What is `createRoot` and what does the `render` method do?

    `createRoot` is a function from the `react-dom/client` library that creates a root for your React application. You pass a DOM node (usually an element with an ID like “root”) to `createRoot`, indicating where React should insert its content. The `render` method, called on the root, then takes a React component and renders it into that DOM node, effectively displaying the UI defined by that component.

    ### How do you write what looks like HTML inside of JavaScript in React?

    React uses JSX (JavaScript XML), a syntax extension to JavaScript. JSX allows you to write HTML-like code within your JavaScript files. This code is then transformed into regular JavaScript function calls by a tool like Babel, ultimately creating the DOM elements that make up your UI.

    ### How can you set up a React project locally on your machine?

    The recommended tool for setting up a React project locally is Vite. You need to have Node.js and npm (Node Package Manager) installed first. Then, you can run the command `npm create vite@latest` in your terminal. This will guide you through a wizard to create a new project, select React as the framework, and choose a variant (like JavaScript). After the project is created, you `cd` into the project directory, run `npm install` to install dependencies, and then `npm run dev` to start a local development server.

    ### How do you separate parts of your app into different components?

    To create a React component, you typically create a new `.jsx` file. You then define a JavaScript function that returns JSX, representing the UI for that component. To use the component in another file (like `index.jsx`), you need to `export` it from its file (usually using `export default`) and `import` it into the other file.

    ### How can you add styling to your components?

    You can style your components using CSS. You can either link an external CSS file or use inline styles. Class names can be applied to JSX elements to connect them to CSS rules defined in your stylesheet.

    ### What are props and how do you use them to pass data between components?

    Props are a way to pass data from a parent component to a child component. They are similar to HTML attributes. You pass props to a component when you use it in JSX, like `<MyComponent name=”John” age={30} />`. Inside the `MyComponent` function, you access these props through the `props` object (e.g., `props.name`, `props.age`). Prop values can be strings, numbers, arrays, objects, or even functions.

    ### What is state in React and how do you update it?

    State is a way for React components to manage and store data that can change over time. You initialize state using the `useState` hook, which returns two values: the current state and a function to update that state (the “state setter”). When you update the state using the state setter, React re-renders the component, reflecting the changes in the UI. When updating state that depends on the previous state value, use the callback function version of the state setter.

    React Components: Structure and Functionality

    React components are fundamental building blocks for creating user interfaces. They are reusable and composable pieces of code.

    Here’s a breakdown of key aspects:

    • Composability and Reusability: Custom components can encapsulate code, allowing you to render them multiple times throughout a document. For example, a custom component called my awesome navbar can include all the code for a navigation bar, and each time you render this component, you’ll get a copy of the navigation bar. If a change is made to the original component, it is reflected everywhere that component is used.
    • JSX Syntax: React utilizes JSX, which looks like HTML within JavaScript, to describe the user interface. Although it looks like HTML, it is actually syntactic sugar on top of react.createElement and returns JavaScript objects. These objects describe what React should place on the page.
    • Pascal Case: Custom components in React must be defined using Pascal case (e.g., TemporaryName). When rendering a custom component, it is typically enclosed in angle brackets, similar to HTML elements (e.g. <TemporaryName />).
    • Declarative Nature: React is declarative, meaning you describe what should be done, and React handles the how. This contrasts with imperative programming, where you need to specify every step.
    • React Elements: React components are functions that return React elements. React elements can be thought of as the React version of HTML elements. JSX syntax is converted into calls to react.createElement, which then turns them into JavaScript objects. React interprets these JavaScript objects and turns them into real DOM (Document Object Model) nodes.
    • Props: React components can receive information in the form of data, and use that to produce reusable components on the page. This is where the concept of “props” comes into play. Props are properties passed down into a component to configure it. Components are not allowed to modify props, as props are immutable or unchangeable.
    • State: State refers to any values that are managed by the component itself. The user interface is a function of the state of your component. React will only run a component if the props that it’s receiving change or it has a state value that changes.
    • Fragments: Fragments are a built-in component from React that allow you to group multiple elements without introducing an extra DOM node. They can be written as <Fragment></Fragment> or with a shorthand <></>.
    • Side Effects: React components should avoid side effects, meaning they should not affect any outside system. An example of a side effect would be making a post request to add an item to a list in a database every time a component runs.
    • Rendering: When React renders a component, it runs the function of that component. This involves executing the code within the component, such as setting up state, defining functions, and returning JSX.

    React State Management: An Overview

    State refers to any values that are managed by the component itself. The user interface is a function of the state of the component, and React will run a component if the props that it’s receiving change or it has a state value that changes. In React, you describe what should be done, and React handles the how. All that is required is to keep the data, or state, of the application up-to-date, and React will handle the rest by updating the view and changing parts of the DOM in reaction to the state change.

    Key aspects of state management:

    • State and Re-rendering A component’s primary job is to take input (props) and return what should be displayed on the screen. React re-renders a component when its state changes.
    • Immutability It is a no-no in React to directly modify the state. Whenever there is a need to change the state, it will never be changed directly.
    • useState Hook To set up a variable that React will place in the view and re-render whenever that state changes, it is necessary to pull in that function from React. A common way to do this is to import a destructured useState Hook from the React library. This function returns an array where the first value is undefined and the second value is a function.
    • Updating State The function that is returned from react.useState, if called and provided with a new value, will re-render the page. This will successfully update the state and trigger React to re-render the page with the new state displayed. When setting state, it is possible to pass the new version of state to replace the old version. The other way is to pass a callback function to the setState function; this callback function will return what the new value of state should be and will receive the old version of state as a parameter.

    There are tools such as Context, Redux, and Zoo that can help avoid having to pass props many levels down in an application.

    React Event Handling: A Comprehensive Guide

    Event handling is a crucial aspect of creating interactive web applications in React, allowing users to interact with elements on the screen.

    Here’s a breakdown of event handling in React:

    • Event Listeners: React implements event listeners through properties that are added to React elements.
    • Naming Convention: Event handler names are camel-cased (e.g., onClick). The syntax is similar to how it is done in HTML.
    • Function Expressions: Instead of setting the attribute equal to a string of a function, it can be set to a JavaScript expression that you want to run.
    • Event Object: Event handler functions have access to the event object, which contains information about the event that was fired. The event object can be used to access data from the element that triggered the event.

    Adding Event Listeners

    • Event listeners can be added as properties to React elements.
    • Instead of using addeventListener to select elements and add a listener, event listeners are added directly in the JSX.
    • It’s possible to define a function outside of the element and then call it in the element. It’s also possible to define a function directly in the element.

    Form Events

    • Forms have their own internal state-holding ability.
    • Forms can use the onSubmit event to handle form submissions.
    • The event.preventDefault() method can be used to prevent the default form submission behavior, such as page refresh.
    • Form data can be accessed using the FormData API.

    Accessibility

    • When disabling elements, it’s important to also set the aria-disabled property to improve accessibility for users with assistive technologies.
    • For dynamically rendered content, use aria-live regions to announce updates to assistive technologies.

    Controlled vs Uncontrolled Components

    • A controlled component is one that React is in control of and does reflect the current value of state.
    • An uncontrolled component is one that React is not in control of and doesn’t reflect the current value of state.

    React Props: Component Data Passing

    Props in React are a mechanism for passing data from parent components to child components, facilitating the creation of reusable and dynamic user interfaces. Props allow components to receive and utilize data, similar to how parameters are passed into a function.

    Key aspects of props passing:

    • Purpose of Props: Props enable the creation of reusable components by allowing them to receive data and customize their behavior. They are a primary means of achieving reusability in React components, making components more flexible and adaptable.
    • Passing Props: Props are passed to components in a way that is similar to passing attributes to HTML elements. For example, if you have a component, you can pass a prop like this: <MyComponent title=”Hello” />.
    • Custom Props: In React, custom props can be defined and passed to components. This differs from HTML elements, where the attributes are predefined by the HTML specification. With React, you have the flexibility to choose the names and types of props that your components accept.
    • Receiving Props: Inside a component, props are received as an object. This object contains all the properties that were passed to the component. It is common to name this object props, but this can be named whatever you want. The data on the props object can be accessed with regular JavaScript using props.name, props.title, and so on.
    • Data Types: Props can accept any JavaScript data type, including strings, numbers, arrays, objects, and even functions. This flexibility allows you to pass complex data structures to components and control their behavior in various ways.
    • Immutability: Components are not allowed to modify props, as props are immutable or unchangeable.
    • One-Way Data Flow: Data can only flow downwards, from a parent component down to its children.
    • Object Destructuring: Object destructuring can be used to extract values from the props object directly within a component. Instead of accessing props using props.name, you can destructure the object to access the name directly const { name } = props;.
    • Spread Syntax: The object spread notation can be used to pass all properties of an object as props to a component. For example, if you have an object called entry, you can pass all its properties as props to a component like this: <MyComponent {…entry} />. React will take all of the individual properties of the entry object and create a new prop that matches each of the properties of this entry object.

    Props enable developers to create modular, reusable, and data-driven components, which are key to building complex and maintainable React applications.

    Code Refactoring: Improving Software Structure and Maintainability

    Code refactoring is the process of restructuring existing computer code without changing its external behavior. It is intended to improve the nonfunctional attributes of the software.

    Here are key considerations for code refactoring, based on the sources:

    • Reasons for Refactoring: One reason to refactor code is to clean it up and make it easier to reason about. Refactoring can reduce the amount of code in a component. After refactoring, code should be easier to maintain.
    • Componentization: During refactoring, it may be helpful to move sections of code into their own components. This can make the code easier to reason about.
    • State Considerations: Refactoring may require critical thinking about how to communicate between parent and child components. This includes deciding whether state needs to move down to a child component or live in the parent component.
    • Single Direction of Data Flow: When refactoring, it is important to set up a React-like way where there is a single source of truth and data flows in one direction, being passed down through props to the components that need it.
    • State Location: It is best practice to keep state as locally defined as it needs to be.
    • Derived State: Take advantage of derived state (state that is computed or derived from existing state) to reduce the need for useState. Ask whether a value needs to be saved in state, or whether it can be derived, and avoid synchronizing data in a side effect using useEffect.
    • Accessibility: While refactoring, keep accessibility in mind when choosing which elements to put on the page. Also, it is important to consider how React is dynamically rendering or removing things from the page, and how to cater the code to those needs.
    Learn React JS – Full Beginner’s Tutorial (2024) & Practice Projects

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Build a SaaS AI Platform with Next.js 13, React, Tailwind, Prisma, Stripe Full Tutorial 2023 – Study Notes

    Build a SaaS AI Platform with Next.js 13, React, Tailwind, Prisma, Stripe Full Tutorial 2023 – Study Notes

    Genius App FAQ

    What is Genius?

    Genius is a full-stack AI-powered SaaS platform offering various AI tools, including:

    • Conversation: An advanced conversational AI model similar to ChatGPT.
    • Image Generation: Creates images from text prompts.
    • Music Generation: Generates music based on your descriptions.
    • Code Generation: Produces code from given instructions.
    • Video Generation: Transforms text prompts into realistic videos.

    How do I access the Genius dashboard?

    Once you have logged in, you can access the dashboard at the URL /dashboard. Only authorized users can view the protected dashboard page.

    What is a Route Group in Next.js?

    Route groups in Next.js are specially named folders that organize your files without affecting the URL structure. For instance, a route group named (marketing) containing a page about.tsx would be accessible via /about and not /marketing/about.

    How does authentication work in Genius?

    Genius utilizes Clerk for authentication, enabling secure user login and registration. You can sign up or log in using your preferred method, such as Google.

    How can I customize the authentication flow?

    Clerk offers customization options for branding and redirect URLs. You can modify the sign-in and sign-up pages, including redirecting users to the /dashboard after successful login.

    What is the free tier usage limit?

    Free tier users have a limit of 5 generations across all AI tools. Once exceeded, a subscription to the Pro plan is required for continued usage.

    How do subscriptions work?

    Genius integrates with Stripe for managing user subscriptions. The Pro plan provides unlimited access to all AI tools. You can manage your subscription and billing details in the /settings page.

    How can I get customer support?

    Genius utilizes Crisp chat for customer support. You can access the chat widget in the lower left corner of the application.

    Genius: AI SaaS Study Guide

    Short Answer Questions (2-3 sentences each)

    1. What is a “full stack production ready software as a service platform”?
    2. Explain the concept of free and subscription tiers in a SaaS platform.
    3. How does the tutorial showcase the functionality of the music generation AI model?
    4. How is customer support integrated into the Genius platform?
    5. What advantage does ChatCNUI offer in terms of component creation?
    6. Explain the purpose and syntax of “route groups” in Next.js.
    7. What is the role of middleware.ts in the context of user authentication?
    8. Describe the integration of Clerk for user authentication in the project.
    9. How does the tutorial handle the display of the currently active page in the sidebar?
    10. What strategy is employed to limit the usage of free tier users?

    Short Answer Key:

    1. A “full stack production ready software as a service platform” is a comprehensive software solution delivered over the internet that includes all the necessary components (frontend, backend, database, etc.) to be deployed and used in a real-world environment.
    2. Free tiers offer limited access to the platform’s functionalities at no cost, attracting users and encouraging them to explore the service. Subscription tiers offer full access and advanced features for a recurring fee, generating revenue for the platform.
    3. The tutorial demonstrates music generation by prompting the AI to create a “piano solo,” resulting in a downloadable audio file. This showcases the model’s ability to generate original audio content.
    4. The tutorial integrates Crisp, a customer support platform, allowing users to report issues. These reports appear in real-time on the Crisp dashboard, enabling platform administrators to respond and assist users effectively.
    5. ChatCNUI simplifies component creation by generating well-structured, typed components. Users can easily customize these components while maintaining code quality and ownership over the component system.
    6. Route groups in Next.js are folders enclosed in parentheses that help organize routes without affecting the URL structure. This allows for better file management without impacting the user-facing URLs.
    7. middleware.ts is a file in Next.js that acts as an intermediary between the client and server, handling tasks like authentication. It checks if a user is logged in before allowing access to protected routes.
    8. Clerk is integrated as the authentication provider, offering pre-built UI components and secure authentication flows. It handles user registration, login, and session management, simplifying the implementation of user access control.
    9. The tutorial uses conditional styling based on the current pathname. If the pathname matches a specific route, the corresponding sidebar link is highlighted, indicating the currently active page to the user.
    10. The tutorial uses Prisma and a “user API limit” model to track the number of API calls made by free tier users. Once a user exceeds the defined limit, access to further API calls is restricted, prompting an upgrade to a paid tier.

    Essay Format Questions:

    1. Analyze the benefits and challenges of utilizing a pre-built component library like ChatCNUI in a large-scale SaaS project.
    2. Discuss the importance of authentication and authorization in a SaaS platform. Explain the role of middleware in enforcing these security measures.
    3. Evaluate the chosen approach for limiting free tier usage in Genius. Propose alternative methods and discuss their advantages and disadvantages.
    4. Critically analyze the integration of Stripe for subscription management in Genius. Discuss potential improvements and alternative payment gateway options.
    5. Explain the importance of customer support in a SaaS platform. Analyze the benefits and limitations of using a third-party solution like Crisp for customer communication.

    Glossary of Key Terms:

    • SaaS (Software as a Service): A software distribution model where applications are hosted by a provider and accessed by users over the internet.
    • Full Stack: Refers to the complete set of technologies required to build and run a software application, including frontend, backend, database, and infrastructure.
    • Production Ready: Software that is stable, reliable, and suitable for deployment in a live, real-world environment.
    • Free Tier: A pricing model where users get limited access to a service for free, often with restrictions on features or usage.
    • Subscription Tier: A pricing model where users pay a recurring fee for full access to a service, usually offering more features and higher usage limits.
    • Stripe: A payment processing platform that enables businesses to accept payments online.
    • Clerk: A user authentication and authorization service that provides pre-built UI components and secure authentication flows.
    • Next.js: A React framework for building web applications, offering features like server-side rendering, routing, and API routes.
    • Route Groups: Folders enclosed in parentheses in Next.js that allow for better route organization without affecting the URL structure.
    • middleware.ts: A file in Next.js that handles tasks like authentication by intercepting requests between the client and server.
    • Prisma: An ORM (Object Relational Mapper) that simplifies database interactions in Node.js applications.
    • PlanetScale: A serverless database platform that provides a scalable and managed MySQL database.
    • API Limit: A restriction on the number of API calls a user can make within a specific timeframe.
    • React Hot Toast: A library for displaying toast notifications in React applications.
    • Crisp: A customer support platform that offers chat, email, and knowledge base features.
    • Typewriter Effect: A library for creating a typing animation effect in React applications.
    • Lucid React: A library that provides a collection of SVG icons for use in React applications.
    • ChatCNUI: A tool for generating React components with predefined styles and functionality.
    • Zod: A TypeScript-first schema validation library that helps ensure data integrity.
    • Hook Form: A form management library for React that simplifies form validation and state management.
    • Replicate AI: A platform for running and sharing machine learning models, used for video and music generation in this project.
    • ZeroScope: A platform for monitoring and managing Replicate AI models.
    • Webhook: An automated notification sent from one application to another when a specific event occurs.
    • Hydration: The process of adding interactivity to server-rendered HTML by attaching JavaScript event handlers and state.

    This comprehensive study guide will help you review the key concepts and technical implementations detailed in the provided source material. By completing the activities and reviewing the glossary, you can gain a deeper understanding of the process involved in building a functional and engaging AI SaaS platform.

    Genius: An AI-Powered SaaS Platform

    I. Landing Page Components

    A. Landing Navbar (/components/LandingNavbar.tsx)

    This client-side React component renders the navigation bar specifically designed for the landing page. It conditionally displays links based on user authentication status, leading to the dashboard for logged-in users and sign-up for non-authenticated users. The navbar prominently features the platform’s logo and a “Get Started” button, encouraging immediate user engagement.

    B. Landing Hero (/components/LandingHero.tsx)

    The LandingHero component constitutes the main visual and textual element of the landing page. It showcases the platform’s core value proposition: “The best AI tools.” A dynamic Typewriter effect highlights key AI functionalities, captivating user attention. This client-side component also includes a call to action, leading users to the sign-up or dashboard based on their authentication status.

    II. Core Application Structure

    A. App Layout (/app/layout.tsx)

    This root layout component provides a consistent structure for the entire application. It includes essential providers for modals, toast notifications, and Crisp chat functionality, ensuring a seamless user experience.

    B. Dashboard Layout (/app/dashboard/layout.tsx)

    This layout component specifically structures the user dashboard. It utilizes server-side rendering to fetch the user’s API limit count and dynamically passes it as a prop to the sidebar component. This design leverages Next.js features for enhanced performance and data handling.

    III. AI Functionality and User Management

    A. Sidebar (/components/Sidebar.tsx)

    The Sidebar component provides navigation for the various AI tools offered by Genius. It displays a list of routes, each featuring an icon, label, and dynamically applied color based on the currently active page. The component integrates with user API limit data to display the user’s remaining free uses.

    B. Free Counter (/components/FreeCounter.tsx)

    This client-side component visually represents the user’s free usage quota within the sidebar. It utilizes the API limit count received as a prop to display the current usage against the maximum allowed free generations. The component features an “Upgrade” button, prompting users to subscribe to the pro plan upon exhausting their free quota.

    C. Subscription Button (/components/SubscriptionButton.tsx)

    The SubscriptionButton component dynamically renders different button actions depending on the user’s subscription status. It displays “Manage Subscription” for Pro users and “Upgrade” for free-tier users, seamlessly guiding users through the subscription management process.

    D. Pro Model (/components/ProModel.tsx)

    This client-side component acts as a modal, triggered when a free-tier user attempts to exceed their usage limits. It showcases the benefits of the Pro plan by listing all available AI tools, highlighting their value proposition. The modal includes a “Subscribe” button, directing users to the subscription checkout flow.

    E. API Limit Management (/lib/api-limit.ts)

    This module contains utilities for managing user API limits. It defines functions to increment user API usage counts whenever an AI tool is used and to check if a user has exceeded their free usage limits. The module integrates with Prisma to store and retrieve API usage data for each user.

    F. Subscription Management (/lib/subscription.ts)

    This module provides utilities for handling user subscriptions. It defines a function to check if a user has an active Pro subscription, taking into account subscription validity and expiration dates. The module integrates with Prisma to access user subscription data.

    G. Stripe Integration (/lib/stripe.ts)

    This module encapsulates the integration with the Stripe API for managing user subscriptions. It initializes the Stripe client and provides functionalities for creating and managing subscriptions, including interacting with Stripe webhooks for handling subscription events and updates.

    H. Stripe API Route (/app/api/stripe/route.ts)

    This server-side API route handles interactions with the Stripe API for creating and managing user subscriptions. It receives requests from the client-side subscription button component and interacts with the Stripe API to initiate checkout sessions and manage subscription updates based on webhook events.

    IV. Individual AI Tool Components

    A. Conversation Page (/app/dashboard/routes/conversation/page.tsx)

    This component implements the core user interface for the conversation AI tool. It includes a form for user input, utilizes the OpenAI API to generate responses, and displays the conversation history. The component integrates with the API limit management module to enforce free-tier usage limits and trigger the Pro Model modal when necessary.

    B. Code Generation Page (/app/dashboard/routes/code/page.tsx)

    C. Image Generation Page (/app/dashboard/routes/image/page.tsx)

    D. Music Generation Page (/app/dashboard/routes/music/page.tsx)

    E. Video Generation Page (/app/dashboard/routes/video/page.tsx)

    These components follow a similar structure to the Conversation Page, offering dedicated interfaces for each specific AI tool. Each component utilizes the corresponding API for generating outputs and integrates with the API limit management module for enforcing usage limits and promoting Pro subscriptions.

    This detailed table of contents provides an in-depth understanding of the code structure and functionality of the Genius platform, encompassing its landing page, core application structure, AI functionalities, and user management features. It facilitates navigation and understanding of the codebase for both developers and anyone interested in learning about the platform’s inner workings.

    Genius AI Platform Briefing Doc

    This briefing document reviews the main themes and functionalities of the Genius AI platform based on provided video transcripts.

    Core Functionality:

    Genius is a full-stack, production-ready SaaS platform offering a range of AI-powered tools, including:

    • Image Generation: Generates images based on user prompts (e.g., “a pretty sunset”).
    • Conversation Model: Provides conversational responses to user queries (e.g., “What is the radius of the Sun?”).
    • Music Generation: Creates audio files in various styles (e.g., “piano solo”).
    • Video Generation: Produces realistic videos based on detailed prompts (e.g., “clown fish swimming around a coral reef”).
    • Code Generation: Generates code snippets based on user instructions (e.g., “simple toggle button using React Hooks”).

    Technology Stack:

    • Next.js: Frontend framework for building dynamic web applications.
    • React: JavaScript library for building user interfaces.
    • Tailwind CSS: Utility-first CSS framework for styling.
    • Clerk: Authentication and user management service.
    • Stripe: Payment processing platform for subscription management.
    • Crisp: Customer support platform for real-time communication.
    • OpenAI: AI models for image, conversation, and code generation.
    • Replicate AI: AI models for video and music generation.
    • Prisma: Database toolkit for connecting to PlanetScale (MySQL).
    • PlanetScale: Serverless MySQL database.
    • Zod: Schema declaration and validation library for form inputs.
    • React Hook Form: Library for managing forms and form data.
    • React Markdown: Library for rendering Markdown content in React components.
    • Typewriter Effect: Library for creating a typewriter animation effect.

    User Experience:

    • Landing Page:Showcases the platform’s capabilities and encourages user signup.
    • Includes a dynamic hero section with a typewriter effect highlighting key features.
    • Offers a prominent “Start Generating for Free” call-to-action button.
    • Dashboard:Provides access to all AI tools via a visually appealing sidebar.
    • Displays a free usage counter, indicating remaining free generations.
    • Offers an “Upgrade to Genius Pro” button for unlocking unlimited usage.
    • AI Tools:Feature consistent UI elements, including heading components with icons, descriptions, and form fields.
    • Implement loading states and empty states for improved user feedback.
    • Leverage React Markdown for displaying structured responses (code snippets, formatted text).
    • Pro Model:A modal window that appears when free usage is exhausted.
    • Showcases the benefits of upgrading to the Pro plan.
    • Includes a visually distinct “Upgrade to Genius Pro” button with a gradient background.
    • Settings Page:Allows users to manage account settings and subscription details.
    • Displays the user’s current subscription status (Free or Pro).
    • Offers a “Manage Subscription” button for Pro users.
    • Error Handling:Uses React Hot Toast to display error messages to the user.
    • Provides informative messages in case of API errors or subscription issues.

    Key Features:

    • Free Tier: Allows users to explore the platform with limited free generations.
    • Monthly Subscription: Unlocks unlimited usage of all AI tools.
    • API Limits: Enforces usage limits for free tier users.
    • Stripe Integration: Manages subscription payments and user access levels.
    • Customer Support: Integrated Crisp chat for real-time customer assistance.

    Development Considerations:

    • Route Groups: Utilizes Next.js route groups to organize code without affecting URL structure.
    • Server Components: Leverages server components for database access and sensitive operations.
    • Client Components: Employs client components for UI interactions and state management.
    • Hydration Errors: Implements safeguards to prevent hydration errors caused by client-side logic in server components.
    • Code Reusability: Creates reusable UI components, such as buttons, cards, and headings.

    Quotes:

    • “This is not going to be your average AI tutorial. We are going to build a full-stack production-ready software as a service platform.”
    • “What would a software as a service be without customer support? In this tutorial, I’m also going to teach you how to build beautiful customer support using Crisp.”
    • “Genius is thinking…” (Loading state message)
    • “Understand, no conversation started.” (Empty state message for conversation model)
    • “Free trial has expired.” (Error message for exceeding free usage)

    Conclusion:

    Genius is a comprehensive AI platform offering a range of powerful tools and a user-friendly experience. The platform leverages a modern technology stack, implements robust error handling, and offers both free and paid subscription options. The integration of Clerk, Stripe, and Crisp ensures seamless authentication, payment processing, and customer support.

    Here is a summary of how the application in the sources utilizes both server and client components:

    • Server Components for Data Fetching and Authentication: The application leverages server components for critical tasks such as fetching data from the database using Prisma and handling authentication with Clerk. These operations are performed on the server side, ensuring data security and efficient handling of sensitive information. [1-6]
    • Client Components for Interactive UI Elements: Client components are employed for interactive elements within the user interface. Components like the sidebar, buttons, modals, and forms are rendered on the client side. This approach enhances user experience by enabling dynamic updates and interactions without requiring full page reloads. [7-15]
    • Server Components for API Routes: The application utilizes server components to define API routes that connect to external services like OpenAI and Replicate AI for AI functionalities. These routes handle requests from the client, interact with the AI APIs, and return the generated results back to the client. [16-20]
    • Client Components for Displaying AI Results: Client components are responsible for displaying the AI-generated results, such as conversation responses, code snippets, images, and music, to the user. They dynamically update the user interface based on the data received from the server-side API routes. [21-24]
    • Hydration and Server Component Refresh: The application employs techniques like router.refresh to rehydrate server components, ensuring that they fetch the latest data from the database after changes occur. This mechanism keeps the UI synchronized with the server-side state, providing a seamless experience for the user. [21, 25]

    The sources indicate that this architectural pattern, using both server and client components, offers several benefits, including improved security, enhanced user experience through dynamic interactions, and efficient data management.

    Here are the AI models implemented in the project discussed in the sources:

    • Image Generation: This model allows users to generate images based on text prompts. The user can specify the number of images and the resolution they desire. The model uses OpenAI’s DALL-E to generate the images. [1-3]
    • Video Generation: This model enables users to generate videos from text prompts. It utilizes the Zeroscope AI model from Replicate AI. [4, 5]
    • Conversation: This model functions as a conversational AI chatbot, allowing users to ask questions and receive responses. It employs the GPT-3.5-turbo model from OpenAI. [6-8]
    • Music Generation: Users can generate music based on text prompts with this model. It uses the “refusion” model from Replicate AI to create audio files. [6, 9]
    • Code Generation: This model allows users to generate code snippets using descriptive text prompts. It utilizes OpenAI and is designed to provide code in markdown format with comments for explanations. [8, 10-12]

    The sources indicate that the project aims to be a full-stack, production-ready SaaS platform with a free tier and a monthly subscription tier using Stripe. The tutorial teaches users how to build these AI tools and implement features like user authentication, API limits, customer support using Crisp, and a landing page. [1, 6, 13-16]

    The application uses Clerk for user authentication and Stripe for subscription management. Here’s a breakdown:

    Authentication

    • Users can sign in with their Google accounts or email addresses. [1]
    • Clerk handles the authentication process, providing sign-in and sign-up pages and managing user sessions. [2]
    • The application uses the app router from Next.js and has specific routes for sign-up and sign-in. [2]
    • Middleware is used to protect routes, redirecting unauthorized users to the sign-in page. [3]
    • The landing page is unprotected, allowing access to both logged-in and logged-out users. [3]
    • A User button component provided by Clerk is used on the dashboard, enabling users to sign out. [4]
    • The application controls the redirection URLs after sign-in and sign-out using environment variables. [3, 4]

    Subscription

    • The application offers a free tier with limited AI model usage (five times). [5, 6]
    • Prisma is used to store user API usage limits and subscription data. [7]
    • Each time a user utilizes an AI model, their usage count is incremented in the database. [8]
    • A checkAPIlimit function verifies if the user has exceeded their free usage limit. [9]
    • When a user exceeds their limit, a 403 error is returned, triggering a premium model prompt. [9, 10]
    • The premium model provides an option to upgrade to a Pro plan. [6, 11]
    • Clicking “Upgrade” initiates a Stripe checkout session. [12]
    • The checkout page uses the user’s email address from Clerk and pre-fills product details (Genius Pro, $20/month, unlimited generations). [13]
    • Stripe webhooks handle subscription events (checkout completion and invoice payment). [14]
    • Upon successful checkout, a webhook creates or updates the user subscription in the Prisma database, linking it to the user ID stored in the checkout session metadata. [15, 16]
    • A settings page allows users to manage their subscriptions, including viewing their status and accessing Stripe’s billing portal to cancel or modify their plans. [17]
    • Utilities like checkSubscription determine if a user has an active and valid Pro subscription, affecting UI elements and API access. [18, 19]

    This combination of Clerk and Stripe, along with Prisma for data management, allows for a robust authentication and subscription system that provides both free and paid access to the AI model functionalities.

    Building an AI SaaS Platform

    The sources provide a detailed walkthrough of building a full-stack AI SaaS platform. This discussion will highlight the key considerations and steps involved, drawing upon insights from the sources and prior conversations.

    1. AI Model Selection and Integration:

    • The first step is choosing the AI models that will power your SaaS. The sources focus on five key models: Image Generation (using OpenAI’s DALL-E), Video Generation (using Replicate AI’s Zeroscope), Conversation (using OpenAI’s GPT-3.5-turbo), Music Generation (using Replicate AI’s “refusion”), and Code Generation (using OpenAI). [1-36]
    • Integrating these models involves setting up accounts with the respective providers (OpenAI and Replicate AI) and obtaining API keys. [17, 31]
    • You’ll need to write API routes that handle user requests, interact with the AI model APIs, and return the generated results. [18, 19, 25, 30, 32, 35]

    2. Frontend Development:

    • The frontend should provide an intuitive user interface for interacting with the AI models. [13-16, 22, 27, 28, 33, 34, 37, 38]
    • The sources utilize Next.js with its app router, a React framework for building server-rendered applications. [5, 11]
    • The UI is built using Tailwind CSS for styling and a component library called chat cnui for pre-built UI elements like buttons, cards, and modals. [6-9, 13, 39]
    • Each AI model should have its dedicated page with an input area for user prompts, options for customization (like resolution or number of outputs), and a display area for the generated results. [14, 15, 24, 28, 33, 34]

    3. Authentication and Subscription Management:

    • To manage user access and monetize your SaaS, you need robust authentication and subscription systems. [12, 40, 41]
    • The sources employ Clerk for user authentication, allowing users to sign in using their Google accounts or email addresses. [12]
    • Stripe is used to handle payments and subscriptions, enabling both a free tier with limited usage and a paid Pro tier with unlimited access. [2, 3, 40]

    4. Database Integration:

    • A database is crucial for storing user data, usage limits, and subscription information. [36]
    • The sources choose PlanetScale, a serverless MySQL database platform, for data persistence. [42]
    • Prisma, an ORM (Object-Relational Mapper), is used to interact with the database, simplifying data modeling and querying. [36, 42]

    5. API Limits and Usage Tracking:

    • To enforce the free tier limitations, you’ll need to track user API usage. [36, 43]
    • The sources implement this by creating a “user API limits” table in the database and incrementing the count each time a user utilizes an AI model. [43]
    • A utility function checks if the user has exceeded their free usage limit before processing requests. [44]
    • If the limit is exceeded, the application triggers a premium model prompt, encouraging users to upgrade to the Pro plan. [45, 46]

    6. Customer Support Integration:

    • For user assistance and feedback collection, integrating a customer support solution is beneficial. [4]
    • The sources incorporate Crisp, a customer messaging platform, to provide live chat support. [47]

    7. Landing Page Design:

    • A compelling landing page is essential for attracting users and conveying the value proposition of your AI SaaS. [5]
    • The sources guide you through creating a visually appealing landing page that showcases the available AI models, highlights key features, and includes user testimonials. [38, 48]

    8. Deployment:

    • Finally, you’ll need to deploy your application to a production environment. [48]
    • The sources utilize Vercel, a platform optimized for Next.js applications, for deployment. [48, 49]
    • It’s important to configure environment variables correctly, including API keys, database connection strings, and webhook secrets, for a seamless production setup. [49-51]

    The sources offer a comprehensive roadmap for building a fully functional AI SaaS platform. By following the step-by-step instructions, you can gain valuable insights into the technical intricacies and design choices involved in creating a successful AI-powered business.

    OpenAI and Replicate AI in AI SaaS Development

    The sources primarily focus on building an AI SaaS platform and demonstrate the use of both OpenAI and Replicate AI for powering distinct AI models. This discussion will examine the roles of these two prominent AI providers within the context of the project.

    OpenAI

    OpenAI is a leading artificial intelligence research and deployment company. The sources showcase the use of three specific OpenAI models:

    • DALL-E for Image Generation: This model empowers users to create images from textual descriptions. The source code includes API calls to OpenAI’s image generation endpoint, sending user prompts and parameters like image count and resolution.
    • GPT-3.5-turbo for Conversational AI: This powerful language model serves as the foundation for the conversational chatbot feature. The code demonstrates setting up the model with an initial “system” message to define its role as a code generator, influencing its responses to align with this purpose.
    • Unspecified Model for Code Generation: The sources mention using OpenAI for code generation but don’t explicitly state which specific model is employed. The code highlights configuring the model to output code snippets in markdown format with code comments for explanations.

    The tutorial emphasizes obtaining an OpenAI API key, setting up environment variables, and handling API responses, including potential errors.

    Replicate AI

    Replicate AI is a platform that hosts and runs machine learning models. The sources use Replicate AI for two AI models:

    • Zeroscope for Video Generation: This model allows users to generate videos from text prompts. The code showcases integrating Zeroscope by invoking the replicate.run function, passing the model identifier and the user’s prompt as input. The source code also addresses the potential for long generation times with Replicate AI models and suggests utilizing webhooks for asynchronous processing to improve user experience.
    • “refusion” for Music Generation: This model enables users to create music from text descriptions. The code demonstrates integrating the “refusion” model using the Replicate AI API, similar to the Zeroscope implementation. The source code also acknowledges the potential for copyright issues with AI-generated music and advises caution when playing or sharing the outputs.

    The tutorial guides users through obtaining a Replicate AI API token, adding it to the environment variables, and handling API calls to generate video and music content.

    Key Observations and Insights

    • The sources demonstrate a strategic approach to model selection, leveraging both OpenAI and Replicate AI based on the specific capabilities of each provider for different AI tasks.
    • The source code provides practical examples of integrating and interacting with AI model APIs from both providers, including handling responses, potential errors, and asynchronous processing.
    • The sources highlight considerations like potential copyright concerns with AI-generated content, prompting developers to be mindful of ethical and legal implications.

    By utilizing both OpenAI and Replicate AI, the AI SaaS platform showcased in the sources gains access to a diverse range of AI capabilities, enhancing its functionality and appeal to users seeking various creative and practical applications.

    Subscription Model and API Limits

    The sources describe a freemium model for the AI SaaS platform. Users can access a free tier with limited usage, and a premium tier, called Genius Pro, is available for a monthly subscription fee. This approach allows users to try the platform’s capabilities before committing to a paid plan.

    Free Tier Limits

    The free tier restricts users to five AI model generations across all functionalities. This limit encourages users to experience the platform’s diverse capabilities while controlling resource usage.

    • A counter in the sidebar displays the remaining free generations to the user, providing transparency and a visual reminder of their usage. [1, 2]
    • The application employs Prisma to store user API limits in a database table called “user API limits”. Each time a user utilizes an AI model, their usage count is incremented. [3]
    • Utility functions checkAPIlimit and increaseAPIlimit are used to verify and update user usage counts. [4]

    When a user attempts to exceed their free limit, a 403 error is returned, prompting the premium model to open. [5]

    Premium (Genius Pro) Subscription

    The premium tier, Genius Pro, provides unlimited AI model generations for a monthly fee of $20. [6]

    • The premium model includes a button labeled “Upgrade” that directs users to a Stripe checkout page. [7]
    • The checkout page is pre-filled with the user’s email address from Clerk and includes product details for Genius Pro. [6]
    • Stripe webhooks handle subscription events, creating or updating user subscription data in Prisma upon successful checkout. [8]
    • A dedicated settings page allows users to manage their subscriptions, view their status, and access Stripe’s billing portal to cancel or modify their plan. [9]
    • Utility functions, such as checkSubscription, determine if a user has an active and valid Pro subscription. This information affects UI elements and access to AI models, unlocking unlimited usage for paid users. [10]

    Implementation Details

    • Stripe API: The platform integrates Stripe for handling payments and managing subscriptions. API keys and webhook secrets are stored in environment variables. [8, 11]
    • Prisma ORM: Prisma simplifies database interactions, allowing the application to efficiently store and manage user data, API limits, and subscription information. [12]
    • Next.js API Routes: Serverless functions handle API requests, interact with AI models from OpenAI and Replicate AI, and manage user authentication and subscription logic. [13]

    The combination of a freemium model, robust API limits, and seamless Stripe integration creates a sustainable and user-friendly monetization strategy for the AI SaaS platform. The sources provide a detailed roadmap for implementing this system, allowing developers to replicate and adapt the approach for their own AI-powered applications.

    Implementing Crisp Chat for Customer Support

    The sources demonstrate how to integrate Crisp, a customer messaging platform, into the AI SaaS platform to provide live chat support for users. This enables direct communication with users, facilitating assistance, feedback collection, and issue resolution.

    Crisp Integration Steps

    1. Crisp Account Creation: The first step involves setting up a free Crisp account. During setup, the sources advise using a dummy website URL as this can be updated later when deploying to a live production environment.
    2. Obtaining Website ID: Upon account creation, Crisp provides a unique website ID. This ID is crucial for configuring the Crisp SDK within the application.
    3. Installing the Crisp SDK: The Crisp SDK is installed using the command npm install crisp-sdk-web, adding the necessary library for interacting with Crisp’s chat functionality within the React application.
    4. Creating a Crisp Chat Component: A dedicated component, named crisp.chat.tsx, is created to house the Crisp integration logic. This component uses the useEffect hook to configure the Crisp SDK upon component mount. The crisp.configure method is called, passing the website ID obtained earlier.

    Crisp Provider and Layout Integration

    • To manage the Crisp chat component and ensure proper rendering, a CrispProvider component is created. This provider simply renders the CrispChat component, ensuring that the chat functionality is initialized and available throughout the application.
    • The CrispProvider is then integrated into the main layout file (layout.tsx) of the application. Placing it above the <body> tag ensures that the chat widget is loaded early in the rendering process.

    Key Benefits and Observations

    • Real-time Customer Support: Crisp provides a live chat interface, enabling users to instantly connect with the support team for assistance.
    • Seamless Integration: The Crisp SDK and React integration provide a smooth and straightforward setup process. The CrispChat and CrispProvider components encapsulate the integration logic, ensuring a clean and maintainable codebase.
    • Enhanced User Experience: By incorporating Crisp, the AI SaaS platform offers a readily accessible communication channel for users, fostering a more positive and supportive user experience.

    The integration of Crisp demonstrates a commitment to user satisfaction by providing a direct and responsive support channel. Users encountering issues or having questions can easily reach out for assistance, contributing to a more positive and engaging interaction with the AI SaaS platform.

    Landing Page Design and Deployment

    The sources provide a comprehensive walkthrough of building an AI SaaS application, including crafting an appealing landing page and deploying the project for public access.

    Landing Page Structure and Components

    The landing page is designed to attract potential users and showcase the platform’s capabilities. It consists of the following key components:

    • Landing Navbar: Situated at the top, the navbar features the Genius logo, links to the dashboard (for logged-in users) or sign-up page, and a “Get Started For Free” button with a premium style using a gradient background.
    • Landing Hero: This section occupies the most prominent space on the page, featuring a captivating headline “The Best AI Tools” enhanced by a typewriter effect that dynamically cycles through the platform’s key offerings: Chatbot, Photo Generation, Music Generation, Code Generation, and Video Generation. A concise description emphasizes the platform’s ability to expedite content creation using AI. A premium-styled button encourages users to “Start Generating For Free,” accompanied by a reassuring “No credit card required” message.
    • Landing Content: This section includes testimonials showcasing positive user experiences. The testimonials are presented in a responsive grid layout using cards with a dark background, white text, and no borders. Each card displays the user’s name, title, a brief description of their experience, and an avatar.
    • Footer: The sources don’t explicitly detail the footer content, but it’s common practice to include essential links, copyright information, and contact details in this section.

    Styling and Design Considerations

    The landing page employs a visually appealing and modern design:

    • Dark Background: The page utilizes a dark background color (#111827), creating a sophisticated and tech-focused aesthetic.
    • Gradient Accents: Gradient backgrounds are strategically used for premium buttons and text accents, adding visual interest and highlighting calls to action.
    • Responsive Layout: The landing page uses a responsive grid system to ensure optimal display across various screen sizes, adapting seamlessly to different devices.
    • Custom Font: The Montserrat font is imported from Google Fonts, lending a clean and modern typographic style to the page.
    • Typewriter Effect: The dynamic typewriter effect in the hero section adds dynamism and draws attention to the platform’s core AI features.

    Deployment Process

    The sources outline the deployment process using Vercel, a platform for deploying front-end applications:

    1. Post-Install Script: The package.json file is updated to include a postinstall script that runs prisma generate, ensuring Prisma client generation after installation.
    2. Code Linting: Running npm run lint checks for any code style errors or inconsistencies, promoting code quality and maintainability.
    3. GitHub Repository: The project is initialized as a Git repository and pushed to a new GitHub repository.
    4. Vercel Project Creation: A new project is created on Vercel, linking it to the GitHub repository containing the application’s code.
    5. Environment Variables: Environment variables, including API keys and secrets for OpenAI, Replicate AI, Stripe, and Clerk, are added to the Vercel project settings.
    6. Initial Deployment: The initial deployment is triggered. Note that the next public app URL environment variable will be set to localhost at this stage, requiring adjustments after the initial deployment succeeds.
    • Updating Environment Variables:The next public app URL variable is updated to the deployed application’s URL from Vercel.
    • The Stripe webhook URL is updated to point to the deployed application’s /api/webhook endpoint.
    • The Stripe webhook signing secret is retrieved from Stripe’s dashboard and added to the Vercel environment variables.
    1. Redeployment: The application is redeployed with the updated environment variables.
    2. Database Reset (Optional): For a clean deployment environment, the Prisma database can be reset using npx prisma migrate reset and then pushed to the PlanetScale database using npx prisma db push.

    The deployment process showcases best practices for deploying a modern web application, including utilizing version control, configuring environment variables, and leveraging a dedicated deployment platform like Vercel.

    Key Takeaways and Considerations

    • The landing page plays a crucial role in marketing the AI SaaS platform, providing a visually engaging and informative introduction to its capabilities.
    • The deployment process highlights the importance of setting up environment variables correctly, ensuring the application can access external services and APIs securely.
    • Developers deploying similar applications should adapt the environment variables and deployment steps to match their chosen hosting platforms and services.
    • The sources provide a solid foundation for understanding the process of designing an effective landing page and deploying a complex AI SaaS application.

    Redirection Logic for Login and Signup

    The sources provide a detailed explanation of how the code handles redirection after a user logs in or signs up using Clerk. The primary mechanism for this redirection is environment variables configured within the application and accessed by the Clerk library.

    Environment Variables for Redirection

    Within the application’s .env file (specifically dot.environment), four key environment variables dictate redirection behavior:

    • NEXT_PUBLIC_CLERK_SIGN_IN_URL: Specifies the URL for the sign-in page. The sources set this to /sign-in.
    • NEXT_PUBLIC_CLERK_SIGN_UP_URL: Specifies the URL for the sign-up page. The sources set this to /sign-up.
    • NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: Determines where a user is redirected after a successful login. The sources set this to /dashboard, ensuring users land on the protected dashboard area after logging in.
    • NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: Determines where a user is redirected after successfully creating an account. The sources set this to /dashboard as well, maintaining consistency in user experience after both sign-up and login actions.

    Clerk Integration and Redirection Handling

    The Clerk library utilizes these environment variables to manage the redirection flow. When a user successfully logs in or signs up, Clerk automatically redirects them to the URL specified in the corresponding “after sign-in” or “after sign-up” environment variables.

    Middleware for Public Routes

    The application employs a middleware file (middleware.ts) to control access to specific routes based on authentication status. The middleware allows defining public routes that can be accessed by both logged-in and logged-out users. The landing page (/) is designated as a public route, enabling unrestricted access.

    Manual Redirection

    In addition to Clerk’s automatic redirection, the code implements manual redirection in specific scenarios:

    • Sign-Out: When a user signs out, the after sign-out URL environment variable (set to /) redirects them back to the landing page.
    • Billing Portal: The Stripe integration includes a billing portal where users can manage their subscriptions. When a user clicks on the “Manage Subscription” button in their settings, the application sends a request to a Stripe API route (/api/stripe). If the user has an existing subscription, this route generates a billing portal session and returns a URL to redirect the user to Stripe’s billing portal.

    Key Points and Observations

    • Environment variables provide a centralized and configurable way to manage redirection logic for different authentication events.
    • The Clerk library seamlessly handles redirection based on these environment variables, simplifying the development process.
    • Middleware ensures that protected routes, such as the dashboard, can only be accessed by authenticated users.
    • Manual redirection is implemented for specific scenarios, like sign-out and accessing Stripe’s billing portal, to enhance user experience and control the flow of the application.

    The code’s redirection logic effectively guides users to the appropriate pages after authentication events, creating a smooth and intuitive navigation experience.

    Landing Page Composition: Structure and Elements

    The sources provide a comprehensive guide to building an AI SaaS application, encompassing the creation of an engaging landing page. The landing page aims to entice potential users and highlight the platform’s features through a strategic arrangement of components.

    Key Components

    The landing page comprises the following key elements:

    • Landing Navbar: Positioned at the top, this navbar showcases the Genius logo, along with links that dynamically adjust based on the user’s authentication status. For logged-in users, a link to the dashboard is provided, while for those not logged in, a link to the sign-up page is presented. Additionally, a “Get Started For Free” button is included, featuring a visually appealing premium style implemented using a gradient background. [1]
    • Landing Hero: Occupying a central position on the page, the Landing Hero section aims to capture attention and convey the essence of the platform. It features the bold headline “The Best AI Tools,” further enhanced by a dynamic typewriter effect that sequentially displays the platform’s main offerings: Chatbot, Photo Generation, Music Generation, Code Generation, and Video Generation. [2, 3] A concise descriptive statement emphasizes the platform’s ability to significantly speed up content creation through AI. A prominently displayed button, styled with a premium gradient, encourages users to “Start Generating For Free.” This call to action is accompanied by a reassuring message: “No credit card required,” aiming to reduce friction in user engagement. [3]
    • Landing Content: This section incorporates testimonials designed to showcase positive user experiences with the platform. These testimonials are structured within a responsive grid layout, utilizing cards with a dark background, white text, and no borders. Each card presents the user’s name, title, a succinct description of their experience, and an avatar. [4]
    • Footer: While the sources do not explicitly detail the footer’s content, it’s generally understood that this section would typically contain important links, copyright information, and ways to contact the platform. This understanding is based on common website conventions and is not explicitly mentioned in the provided sources.

    Visual Design and Styling

    The landing page exhibits a visually compelling and modern design through the implementation of various stylistic elements:

    • Dark Background: The page adopts a dark background color (#111827), contributing to a sophisticated and technology-oriented aesthetic. [5]
    • Gradient Accents: Gradient backgrounds are strategically applied to premium-styled buttons and text elements, adding visual depth and drawing attention to calls to action. [1, 3]
    • Responsive Layout: A responsive grid system is employed to ensure optimal display across diverse screen sizes, allowing the landing page to adapt seamlessly to various devices. [4]
    • Custom Font: The Montserrat font, imported from Google Fonts, provides a clean and contemporary typographic style to the landing page. [5]
    • Typewriter Effect: The dynamic typewriter effect within the Landing Hero section introduces a sense of activity and highlights the platform’s core AI features. [3]

    The structure and design of the landing page work cohesively to present a compelling introduction to the AI SaaS platform, emphasizing its key features, benefits, and ease of use.

    Pathways to Premium Features: Unlocking Full Potential

    The sources, which detail the development of an AI SaaS platform, outline a clear path for users to access and enjoy premium features. The model relies on a freemium approach, offering a limited free tier while providing a subscription option to unlock the full power of the platform.

    Freemium Model: A Taste of Genius

    The platform allows users to experience its capabilities through a free tier, granting them a limited number of AI generations. This strategy enables potential subscribers to try the platform’s features firsthand before committing to a paid plan. The sources set this limit to five generations across all AI functionalities (conversation, image generation, music generation, code generation, and video generation) [1-3]. This limit is tracked using Prisma, a database toolkit, to manage and persist user API limits [3, 4].

    Once a user exhausts their allocated free generations, they are prompted to upgrade to the premium plan to continue using the platform [2]. The application elegantly handles this transition by displaying a “Pro Model” prompt, which outlines the benefits of subscribing and provides a clear call to action to upgrade [2, 5].

    Subscription: Embracing Unlimited AI Power

    The sources primarily focus on outlining the technical implementation of the subscription system, using Stripe as the payment gateway [2, 6]. The platform offers a “Genius Pro” subscription plan, priced at $20 per month, which grants users unlimited access to all AI generation capabilities [7].

    While the sources emphasize the technical aspects, they do not explicitly discuss the specific benefits and added features available exclusively to premium subscribers. However, the primary advantage of the subscription plan, heavily implied in the sources and our previous conversation, is the removal of usage limitations imposed by the free tier [2, 7]. This unlimited access empowers users to fully leverage the platform’s capabilities, enabling them to generate content without restrictions.

    Key Takeaways: Accessing Premium Features

    • Limited Free Tier: Users can experiment with the platform’s AI functionalities with a limited number of free generations [1-3].
    • Subscription Model: The “Genius Pro” subscription, priced at $20 per month, unlocks unlimited access to all AI generation features, removing the limitations of the free tier [7].
    • Clear Upgrade Path: When users reach their free usage limit, they are presented with a “Pro Model” prompt, guiding them towards the premium subscription [2, 5].

    The sources predominantly focus on the technical implementation of the freemium and subscription models. While they clearly establish the path for users to access premium features, they do not explicitly detail any exclusive features or functionalities reserved for paying subscribers beyond the removal of usage limits.

    Benefits of PlanetScale for Application Development

    The sources, which provide a detailed walkthrough of building an AI SaaS application, showcase the use of PlanetScale as the database provider. PlanetScale’s unique features and capabilities offer several advantages during application development.

    MySQL Compatibility and Scalability

    PlanetScale leverages the familiar and widely adopted MySQL relational database management system. This compatibility simplifies the development process, as developers can leverage their existing MySQL knowledge and readily integrate the database into the application. [1]

    Moreover, PlanetScale offers seamless scalability, a critical factor for SaaS applications aiming for growth. The platform’s ability to handle increasing data volumes and user traffic ensures a smooth and responsive user experience, even as the application scales to accommodate a larger user base.

    Branching and Non-Blocking Schema Changes

    One of PlanetScale’s standout features, highlighted in our conversation history, is its branching capability, akin to version control systems like Git. [1] This functionality allows developers to create branches for schema modifications, enabling testing and validation of changes in isolated environments without impacting the live production database. This feature significantly reduces risks associated with database migrations and promotes a more agile development workflow.

    Furthermore, PlanetScale supports non-blocking schema changes. [1] This means developers can apply modifications to the database schema without causing downtime or disruptions to the application’s operation. This capability is particularly valuable in SaaS environments, where continuous uptime is crucial for user satisfaction and business continuity.

    Serverless Architecture and Simplified Management

    PlanetScale operates as a serverless database platform, abstracting away the complexities of infrastructure management. [1] This frees developers from the burdens of server provisioning, maintenance, and scaling, allowing them to focus on building and enhancing the application’s core features.

    Integration with Prisma: Seamless Database Interaction

    The application leverages Prisma, a database toolkit, to interact with PlanetScale. [1] Prisma provides a powerful and type-safe ORM (Object-Relational Mapping) layer, simplifying database operations within the application’s code. The combination of PlanetScale’s MySQL compatibility and Prisma’s ease of use streamlines database interaction and enhances developer productivity.

    Benefits Recap:

    • MySQL Compatibility: Facilitates easy integration and leverages developers’ existing MySQL expertise.
    • Scalability: Handles increasing data volumes and user traffic, ensuring optimal performance as the application grows.
    • Branching and Non-Blocking Schema Changes: Promotes safe and agile database schema management without downtime.
    • Serverless Architecture: Simplifies database management by abstracting away infrastructure complexities.
    • Integration with Prisma: Provides a type-safe and user-friendly ORM layer for streamlined database interaction.

    The use of PlanetScale as the database provider offers several advantages for developing the AI SaaS application. Its compatibility, scalability, ease of management, and integration with Prisma contribute to a smooth, efficient, and robust development process.

    The Role of router.refresh() in Updating Server Components

    The sources describe the implementation of an AI SaaS platform using Next.js 13. The application leverages server components for various functionalities, including fetching and displaying the user’s remaining free generations. The use of router.refresh() plays a crucial role in ensuring that server components are rehydrated with the latest data from the database.

    Triggering Server Component Rehydration

    When a user submits a prompt to one of the AI models, the application makes an API request to the corresponding server component to generate the output. After the response is received and processed, the router.refresh() function is called within a finally block. This function, part of the useRouter hook from next/navigation, forces all server components to re-fetch data and update their state.

    Maintaining Accurate Free Generation Count

    In the context of the AI SaaS application, router.refresh() is instrumental in keeping the displayed free generation count accurate. The application uses a server component within the layout.tsx file to fetch and display this count using the getAPIlimitCount() utility function. This function retrieves the count from the PlanetScale database using Prisma.

    Without router.refresh(), the server component responsible for displaying the free generation count would not automatically update after a user consumes a generation. This would result in a stale display, showing an incorrect number of remaining generations. By calling router.refresh() after each API request to an AI model, the application ensures that all server components, including the one responsible for the free generation count, are updated with the latest data from the database.

    Key Benefits of router.refresh()

    • Real-time Data Updates: Ensures that server components reflect the most current data from the database.
    • Simplified State Management: Eliminates the need for manual state updates or complex synchronization mechanisms.
    • Improved User Experience: Provides users with an accurate and up-to-date view of their usage and subscription status.

    The strategic use of router.refresh() in the AI SaaS application simplifies state management and ensures that server components always display the most up-to-date information. This approach contributes to a seamless and responsive user experience, accurately reflecting the user’s remaining free generations and subscription status.

    Platform’s Authentication Mechanism: A Closer Look at Clerk

    The sources outline the development of an AI SaaS application, emphasizing the technical implementation of user authentication using Clerk, a third-party authentication provider.

    Clerk Integration for Simplified Authentication

    The application seamlessly integrates Clerk to handle user authentication, simplifying the often complex process of managing user accounts, passwords, and security measures. Clerk’s integration within the Next.js 13 application follows a structured approach, as detailed in the sources.

    Steps for Clerk Integration:

    • Installation: The clerk/nextjs package is installed using npm, bringing in the necessary components and utilities.
    • Configuration: Environment variables, including the Clerk publishable key and secret key, are set in the .env file. Additional environment variables, such as sign-in and sign-up URLs, and redirect URLs after successful authentication actions, are also configured to customize the authentication flow.
    • Provider Setup: The application wraps its root layout component (layout.tsx) with the ClerkProvider component. This sets up the necessary context for Clerk to manage authentication throughout the application.
    • Middleware Implementation: A middleware file (middleware.ts) is created to define authentication rules and handle redirects. It includes logic to protect specific routes, requiring users to be authenticated before accessing them. The middleware also defines public routes that do not require authentication, ensuring that unauthenticated users can access certain sections of the application, such as the landing page.
    • Sign-in and Sign-up Pages: The application creates dedicated sign-in and sign-up pages using Clerk’s pre-built UI components. These components offer a customizable and user-friendly interface for users to register and authenticate with the platform.
    • User Button: The application utilizes the UserButton component provided by Clerk to display the currently logged-in user’s information. This component allows users to manage their profile and sign out of the application.

    Clerk’s Role in Authentication

    Clerk handles the heavy lifting of user authentication, providing secure mechanisms for user registration, login, password management, and session management. The application leverages Clerk’s pre-built UI components and API to streamline the authentication process, reducing the amount of custom code required.

    By delegating authentication to Clerk, the application benefits from:

    • Simplified Development: Reduces the complexity of building and maintaining authentication logic.
    • Enhanced Security: Leverages Clerk’s robust security measures and best practices.
    • Improved User Experience: Provides users with a seamless and familiar authentication experience.

    Authentication and API Access Control

    The sources also highlight how user authentication, managed by Clerk, plays a crucial role in controlling access to the platform’s API endpoints.

    Unauthorized Access Prevention:

    In the API routes responsible for the various AI models, the auth() function from clerk/nextjs is used to retrieve the user ID of the currently authenticated user. If no user ID is present, indicating an unauthenticated user, the API route returns an “unauthorized” response (401 status code), preventing access to the functionality.

    Premium Feature Access Control:

    The application implements a freemium model, allowing users to access premium features, such as unlimited AI generations, through a paid subscription. The checkAPIlimit() utility function, which relies on the user ID retrieved from auth(), determines whether the user is authorized to access the requested functionality based on their subscription status.

    Key Takeaways

    • Clerk Integration: The application seamlessly integrates Clerk, a third-party authentication provider, to manage user authentication.
    • Simplified Authentication: Clerk’s pre-built UI components and API streamline the authentication process, reducing development complexity.
    • Secure and User-friendly: Clerk enhances security and provides a familiar authentication experience for users.
    • API Access Control: User authentication, managed by Clerk, is used to control access to API endpoints, ensuring that only authorized users can access specific functionalities.

    The sources provide a comprehensive overview of how the AI SaaS platform handles user authentication using Clerk. By leveraging Clerk’s capabilities, the application simplifies authentication management, enhances security, and controls access to premium features based on user subscription status.

    Benefits of the Vercel AI SDK: Expanding on the Potential

    While the sources provide a detailed walkthrough of building an AI SaaS application using Next.js 13 and various AI providers like OpenAI and Replicate, they don’t directly mention or utilize the Vercel AI SDK. However, based on the application’s structure and challenges encountered, it’s possible to explore how incorporating the Vercel AI SDK could potentially enhance the platform.

    Addressing API Route Timeout Issues with Edge Functions

    The sources mention that deploying the application on Vercel’s free “Hobby” plan might lead to timeout issues for AI models with longer generation times, such as music or video generation. This limitation arises from the serverless function execution time constraints on the Hobby plan.

    The Vercel AI SDK, designed for deploying and managing AI models on Vercel’s edge network, could provide a solution to these timeout challenges. By leveraging edge functions, which execute closer to users and offer increased execution time limits, the application could accommodate AI models with longer processing times without requiring an upgrade to a higher-tier Vercel plan. This approach would improve the reliability and responsiveness of the platform, ensuring a smoother user experience, especially for resource-intensive AI models.

    Streamlining AI Model Deployment and Management

    The sources demonstrate the process of integrating and interacting with different AI providers, including OpenAI and Replicate. While the integration steps are well-explained, managing multiple providers and their specific APIs could introduce complexity to the application’s codebase.

    The Vercel AI SDK aims to simplify AI model deployment and management on the Vercel platform. It provides a unified interface for interacting with various AI providers, potentially streamlining the integration process and reducing code complexity. This could lead to a more maintainable and scalable codebase, facilitating easier adoption of new AI models and providers in the future.

    Potential for Enhanced Performance and Scalability

    The Vercel AI SDK leverages the power of Vercel’s edge network, known for its low latency and global distribution. Deploying AI models through the SDK could potentially lead to improved performance and scalability for the AI SaaS application.

    By executing AI models closer to users on the edge, the application could reduce response times and enhance the overall user experience. Additionally, the scalability of the edge network ensures that the platform can handle increased traffic and demand as the user base grows.

    Important Considerations

    • The information regarding the Vercel AI SDK and its potential benefits is not explicitly derived from the sources. It is based on general knowledge of the SDK and its capabilities.
    • Further research and testing would be necessary to validate the specific advantages of using the Vercel AI SDK within the context of this particular AI SaaS application.

    While the sources do not explicitly mention the Vercel AI SDK, its features, particularly the use of edge functions and a unified interface for AI providers, could potentially address the challenges of API timeout limitations and streamline the management of multiple AI providers. Further exploration and testing would be needed to confirm the specific benefits within the application’s context.

    Handling Subscription Payments: The Stripe API in Action

    The sources provide a detailed walkthrough of integrating the Stripe API into an AI SaaS application to manage user subscriptions and payments. They outline the steps involved in setting up Stripe, creating checkout sessions, handling webhooks, and managing user subscriptions within the application.

    Stripe Account Setup and API Key Configuration

    • Account Creation: The first step involves creating a Stripe account and navigating to the developer dashboard to obtain the necessary API keys.
    • Secret Key Storage: The Stripe secret key, crucial for secure API communication, is stored in the application’s environment variables (.env file).
    • Stripe Client Initialization: A Stripe client is initialized within a utility file (stripe.ts) using the secret key. This client is used to interact with the Stripe API throughout the application.

    Creating a Subscription Checkout Flow

    • Stripe Route: A dedicated API route (/api/stripe) is created to handle subscription requests. This route utilizes the Stripe client to manage checkout sessions and billing portal interactions.
    • Authentication Check: Upon receiving a request, the route first verifies if the user is authenticated using Clerk. If not, it returns an unauthorized response.
    • Existing Subscription Check: If the user is authenticated, the route checks if they already have an active subscription.
    • Billing Portal Redirection: If an active subscription exists, the route uses the billing_portal.sessions.create() method from the Stripe API to generate a billing portal session and redirects the user to it. This allows users to manage their existing subscriptions, including upgrades, cancellations, and payment method updates.
    • Checkout Session Creation: If no active subscription is found, the route utilizes the checkout.sessions.create() method to generate a new checkout session. This session includes details about the subscription plan, such as pricing, billing interval, and product information.
    • Essential Metadata: Critically, the checkout session includes the user’s ID as metadata. This metadata is crucial for linking the checkout session with the corresponding user in the application’s database, ensuring that the subscription is correctly assigned.
    • Checkout URL Return: In both cases (billing portal or checkout session), the route returns a JSON response containing the URL for the generated session. This URL is used on the client-side to redirect the user to the appropriate Stripe interface.

    Handling Webhooks for Subscription Events

    Stripe webhooks play a crucial role in notifying the application about events related to user subscriptions, such as successful payments, subscription updates, and cancellations.

    • Webhook Route Creation: The application sets up a dedicated API route (/api/webhook) to handle incoming webhook events from Stripe.
    • Webhook Secret Configuration: A webhook signing secret, obtained from the Stripe dashboard, is securely stored in the application’s environment variables. This secret is used to verify the authenticity of incoming webhooks, ensuring they are indeed from Stripe.
    • Event Handling: The webhook route uses the stripe.webhooks.constructEvent() function to verify the signature of the incoming webhook and parse the event data. The route then handles different event types:
    • checkout.session.completed: This event is triggered when a user successfully completes a checkout session and subscribes to a plan. The route retrieves the subscription details from Stripe, creates a new user subscription record in the application’s database, and links it to the user using the metadata included in the checkout session.
    • invoice.payment_succeeded: This event is triggered when an invoice payment for a subscription is successful, often indicating a renewal. The route updates the existing user subscription in the database, reflecting the new billing period and potentially any changes in the subscription plan.
    • Response and Security: The webhook route returns a 200 OK response to Stripe, acknowledging successful event processing. The route is secured using Clerk middleware, ensuring that only authenticated requests from Stripe are processed.

    Managing User Subscriptions Within the Application

    • Subscription Status Check: The application utilizes a utility function (checkSubscription()) to check the current subscription status of a user. This function retrieves subscription data from the database using the user ID and validates whether the subscription is active and within the current billing period.
    • Subscription Button Logic: A dedicated component (SubscriptionButton) handles the user interface for managing subscriptions. Depending on the user’s current subscription status, the button either displays “Manage Subscription” (for active subscribers) or “Upgrade” (for free users). Clicking the button triggers an API call to the /api/stripe route, which, as explained earlier, either redirects the user to the billing portal or initiates a new checkout session.
    • Freemium Model Enforcement: The application implements a freemium model, granting free users a limited number of AI generations. API routes for various AI models use the checkAPIlimit() function to determine if a user has exceeded their free limit. If so, they are presented with the ProModel, encouraging them to upgrade.
    • API Limit Management: The application tracks the number of API calls made by free users using the increaseAPIlimit() utility function, which updates a user’s usage count in the database.

    Key Concepts and Insights

    • Seamless Integration: The Stripe API integration within the AI SaaS application is thorough, encompassing account setup, checkout flows, webhook handling, and subscription management.
    • Security Considerations: The application emphasizes security by storing sensitive API keys in environment variables and verifying the authenticity of incoming Stripe webhooks.
    • Freemium Model and API Limits: The sources clearly demonstrate how to implement and enforce a freemium model, using Stripe for premium subscriptions and API limits to control free usage.
    • Importance of Metadata: The use of metadata in checkout sessions is crucial for linking Stripe events with corresponding users within the application.

    The sources provide a comprehensive overview of how the Stripe API is leveraged to handle subscription payments and manage user subscriptions within the AI SaaS platform. The integration demonstrates key concepts in payment processing, webhook management, subscription lifecycle management, and secure API communication.

    Free Trial Exhausted: Encouraging the Upgrade

    The application implements a freemium model, allowing free users a limited number of AI generations before prompting them to upgrade to a paid subscription. Here’s a breakdown of what happens when a free user exceeds their limit:

    • API Limit Check: The API routes for each AI feature (conversation, code generation, image generation, music generation, video generation) utilize the checkAPIlimit() function. This function queries the application’s database to determine if the user has surpassed their allotted free generations. [1]
    • 403 Forbidden Response: If the free limit is exceeded, the API route returns a NextResponse with a 403 Forbidden status code. This status code signifies that the user is not authorized to access the requested resource (the AI generation). [2]
    • Client-Side Error Handling: The front-end application intercepts this 403 error within the onSubmit function of each AI component. [3, 4]
    • Pro Model Trigger: Upon detecting the 403 error, the client-side code triggers the ProModel component, which presents a modal window to the user. [3, 4]
    • Upgrade Prompt: The ProModel displays information about the benefits of upgrading to a paid “Genius Pro” subscription, emphasizing the removal of generation limits. [3]
    • Subscription Button: The modal includes a prominent “Upgrade” button, styled distinctively to encourage user action. [5]
    • Stripe Integration: Clicking the “Upgrade” button initiates the Stripe checkout flow, as detailed in a previous response, guiding the user through the subscription purchase process. [6]

    In essence, when a free user exhausts their allotted generations, the application gracefully handles the situation by:

    1. Blocking further free access to the AI features.
    2. Presenting a clear upgrade prompt, highlighting the advantages of a paid subscription.
    3. Seamlessly integrating with Stripe, facilitating a smooth subscription purchase experience.

    This approach effectively encourages free users to convert to paying subscribers while maintaining a positive user experience.

    Navigating the Free Tiers: OpenAI and Replicate AI

    While the sources primarily focus on building an AI SaaS application and integrating Stripe for subscriptions, they do offer some insights into the free tiers provided by OpenAI and Replicate AI.

    OpenAI’s Free Trial

    The sources mention that OpenAI offers a free trial for new users. [1] This trial provides a specific amount of credit, potentially $5, that users can utilize within the first three months of account creation. [1] However, the exact details of OpenAI’s current free tier offerings are not explicitly stated in the sources. The information provided pertains to the speaker’s experience during the tutorial’s development. To obtain the most up-to-date information on OpenAI’s free tier, it is recommended to consult their official website or documentation.

    Replicate AI’s Free Tier

    The sources highlight that Replicate AI also offers a free tier for users. [2] Unlike OpenAI, the specific details of Replicate AI’s free tier are not explicitly outlined in the sources. It is suggested that users exercise caution and avoid excessive API requests to stay within the free usage limits. [2] Similar to OpenAI, to get the most accurate and current information on Replicate AI’s free tier, it would be best to refer to their official website or documentation.

    Insights from the Sources

    • Emphasis on Cost-Effectiveness: The sources emphasize that both OpenAI and Replicate AI offer free tiers, enabling developers to build and experiment with AI applications without incurring immediate costs.
    • Limited Information on Specifics: The sources provide limited information about the exact features, usage limits, and credit allocations within the free tiers of both platforms. It is implied that these details may vary and are subject to change.
    • Recommendation for Independent Verification: The sources suggest that users refer to the official documentation or websites of OpenAI and Replicate AI to obtain the most up-to-date and accurate information on their free tier offerings.

    The sources provide an overview of the existence of free tiers for both OpenAI and Replicate AI but lack specific details about their current offerings. For comprehensive information, it is advisable to consult the official resources of both platforms.

    Vercel Hobby Plan Limitations: Insights from the Sources

    While the sources primarily focus on building an AI SaaS application and integrating various services like Stripe, OpenAI, and Replicate AI, they touch upon the limitations of deploying such an application on Vercel’s Hobby plan, specifically concerning API route timeouts.

    API Timeout Challenges on the Hobby Plan

    The sources highlight that deploying the developed AI SaaS application on Vercel’s free Hobby plan can lead to challenges, particularly with AI models that require extensive processing time. The speaker notes that certain actions, such as music or video generation, may take a significant amount of time, potentially exceeding the timeout limits imposed by the Hobby plan.

    • Exceeding Timeout Limits: The sources explain that if an API route takes too long to process a request (e.g., generating a complex music piece or video), it might hit the timeout limit enforced by the Hobby plan, resulting in errors. This is especially relevant for AI models that inherently involve substantial computation and processing time.
    • Impact on User Experience: API timeouts can negatively impact the user experience. If a user initiates a request for a computationally intensive AI generation and encounters a timeout error, it can lead to frustration and a perception of unreliability.

    Potential Solutions and Alternatives

    The sources suggest a few potential solutions or alternatives to mitigate the limitations of using the Vercel Hobby plan for this type of AI application:

    • Upgrading to a Higher Plan: Vercel offers paid plans with more generous resource allocations, including longer API route timeout limits. Upgrading to a paid plan could provide the necessary headroom to accommodate the processing time required for complex AI models.
    • Exploring Vercel AI SDK: The speaker mentions the Vercel AI SDK as a potential alternative. While not explicitly covered in the provided sources, the speaker indicates that this SDK, designed for AI applications, offers advantages such as longer timeouts, faster processing through edge network utilization, and support for content streaming.

    Key Points and Observations

    • Hobby Plan Suitability: The sources imply that Vercel’s Hobby plan, while suitable for many applications, might not be the ideal choice for production-level AI SaaS platforms that involve computationally intensive models with longer processing times.
    • Timeout Constraints: The limited API timeout on the Hobby plan can lead to errors and disruptions for users if AI generation requests exceed the allowed processing duration.
    • Mitigation Strategies: The sources briefly touch upon potential solutions, such as upgrading to a paid Vercel plan or exploring the capabilities of the Vercel AI SDK, which is designed to handle the demands of AI workloads more effectively.

    The sources provide a glimpse into the limitations of using Vercel’s Hobby plan for production-level AI applications, specifically highlighting the potential for API timeouts when dealing with resource-intensive AI models. The information, however, is presented in a conversational context and primarily focuses on guiding users through the tutorial, rather than providing an exhaustive analysis of Vercel’s pricing plans or alternatives. For a more in-depth understanding of Vercel’s offerings and the best deployment options for your specific application, it is recommended to consult Vercel’s official documentation and explore their various plans and features.

    metadata: Connecting Stripe Checkouts with Users

    The metadata object plays a crucial role in linking a successful Stripe checkout session back to the specific user who made the purchase in the application. The sources emphasize that this is essential for managing user subscriptions effectively.

    The Challenge: Anonymous Checkouts

    When a user initiates a Stripe checkout, the process occurs independently of the main application. Stripe handles the payment flow, and the application only receives notifications about the outcome (success or failure). The challenge is that, by default, the checkout process doesn’t provide a direct link between the payment and the user’s account in the application.

    metadata: Bridging the Gap

    The metadata object within the Stripe checkout session serves as this crucial bridge. It allows developers to embed custom information into the checkout session. In the context of the AI SaaS application, the critical piece of information passed within metadata is the user ID.

    How metadata Works:

    1. Checkout Session Creation: When creating a Stripe checkout session using stripe.checkout.sessions.create(), the application includes the logged-in user’s ID within the metadata object.
    2. metadata: {
    3. userId: user.id,
    4. }
    5. Webhook Event: Upon a successful checkout (signaled by the checkout.session.completed event), Stripe sends a webhook notification to the application’s designated webhook endpoint.
    6. User Identification: The webhook handler, using the Stripe API, retrieves the completed checkout session details. Crucially, it accesses the metadata object within the session to extract the stored userId.
    7. Subscription Creation/Update: Armed with the userId, the application can now:
    • Create a new subscription record in its database, associating the Stripe subscription details with the correct user.
    • Update an existing subscription record if the user is renewing or modifying their plan.

    Importance of metadata:

    • Accurate Subscription Management: Without the user ID in metadata, the application wouldn’t know which user to grant the subscription to, leading to discrepancies and potential revenue loss.
    • Personalized User Experience: Knowing the subscribed user allows the application to unlock premium features, display personalized billing information, and tailor the user experience accordingly.

    The metadata object is a subtle but powerful tool within Stripe’s checkout flow. It ensures that successful checkouts are correctly linked to the corresponding users in the application, enabling robust subscription management and a seamless user experience.

    Installing Prisma as a Development Dependency

    Running the command npm install -D prisma installs Prisma as a development dependency in your project. Let’s break down this command and understand its purpose within the context of building the AI SaaS application described in the sources.

    Understanding the Command:

    • npm: This is the Node Package Manager, a command-line tool used to manage packages (libraries, frameworks, tools) in Node.js projects.
    • install: This subcommand instructs npm to install a specific package.
    • -D: This flag, short for –save-dev, indicates that the package should be installed as a development dependency.
    • prisma: This is the name of the package we want to install—the Prisma ORM (Object-Relational Mapper).

    Development Dependencies vs. Regular Dependencies:

    In Node.js projects, dependencies are categorized into two types:

    • Regular Dependencies: These are packages that are essential for the application to run in production. They are included in the final production build.
    • Development Dependencies: These are packages that are used during development but are not needed for the application to function in a production environment. Examples include testing frameworks, code linters, and build tools.

    Why Prisma is a Development Dependency:

    Prisma, while crucial for database interactions during development, is typically not required in the production runtime environment.

    • Database Schema Management: Prisma is primarily used to define and manage the database schema, generate type-safe database clients, and interact with the database during development. These tasks are typically performed during the development and build phases.
    • Production Deployment: In production, the database schema is often considered static, and the application interacts with the database through the generated Prisma client, which can be included in the production build.
    • Optimization: Installing Prisma as a development dependency helps keep the production build leaner, as it excludes unnecessary packages that are not directly involved in the runtime execution of the application.

    Prisma’s Role in the AI SaaS Application:

    In the sources, Prisma is used to:

    • Define the Database Schema: The schema.prisma file defines the data models for user API limits (user_api_limit) and user subscriptions (user_subscription).
    • Generate a Type-Safe Client: The command npx Prisma generate generates a type-safe Prisma client, which provides functions to interact with the database in a way that is checked by TypeScript.
    • Manage Database Migrations: The command npx Prisma db push pushes changes in the data model to the database, effectively managing database migrations.
    • Query and Update Data: The application code uses the generated Prisma client to query and update data in the database (e.g., checking API limits, storing subscription details).

    Key Points:

    • npm install -D prisma installs Prisma as a development dependency, meaning it is used during development but is not included in the production build.
    • Development dependencies are useful for tools and libraries needed during development, but not for the runtime execution of the application.
    • Prisma, as an ORM, is mainly used for schema management, client generation, and database interactions during development.
    • The generated Prisma client is included in the production build, allowing the application to communicate with the database in a type-safe manner.

    By understanding the concept of development dependencies and Prisma’s role in the application, you can see why npm install -D prisma is a logical choice for this project.

    Implementing the “Pro Model” Loading State

    The sources describe the implementation of a “Pro Model” component that appears when a user has exceeded their free API usage limits or clicks on an “Upgrade” button. Here’s how a loading state is integrated into this component:

    1. Initializing the Loading State

    Within the ProModel component, a loading state is initialized using React’s useState hook:

    const [loading, setLoading] = useState(false);

    This creates a state variable loading with an initial value of false, indicating that the model is not in a loading state by default. The setLoading function allows you to update the loading state.

    2. Triggering the Loading State

    The loading state is triggered in the onSubscribe function, which is executed when the user clicks the “Upgrade” button within the “Pro Model”. Here’s the relevant code:

    const onSubscribe = async () => {

    try {

    setLoading(true); // Activate loading state

    // … Axios request to initiate Stripe checkout

    } catch (error) {

    // … Error handling

    } finally {

    setLoading(false); // Deactivate loading state

    }

    };

    When the “Upgrade” button is clicked:

    • setLoading(true) is called to set the loading state to true, indicating that an operation is in progress.
    • An Axios GET request is sent to the /api/stripe endpoint to initiate the Stripe checkout process.
    • In the finally block, setLoading(false) is called to deactivate the loading state, regardless of whether the checkout request was successful or resulted in an error.

    3. Using the Loading State in the Button

    The loading state variable is used to control the disabled state of the “Upgrade” button:

    <Button

    // … other props

    disabled={loading}

    onClick={onSubscribe}

    >

    Upgrade

    </Button>

    • When loading is true, the button becomes disabled, preventing the user from clicking it again while the checkout process is ongoing.
    • When loading is false, the button is enabled, allowing the user to initiate the checkout flow.

    Enhancements: Visual Feedback (Not in Sources)

    The sources primarily focus on the functional aspect of disabling the button during the loading state. To provide a better user experience, you could enhance the loading state implementation by adding visual feedback. Here are a few ideas that are not explicitly covered in the sources and would require additional code and potentially external libraries:

    • Spinner: Display a loading spinner or animation within the button while loading is true.
    • Text Change: Change the button text to “Upgrading…” or a similar message to indicate the action in progress.
    • Overlay: Add a semi-transparent overlay over the entire “Pro Model” content to visually emphasize that an operation is ongoing.

    Key Points

    • The loading state prevents multiple clicks on the “Upgrade” button while the Stripe checkout is in progress.
    • The useState hook is used to manage the loading state variable.
    • The disabled prop of the Button component is controlled by the loading state.
    • Consider adding visual feedback elements to enhance the user experience during the loading state.

    By implementing a loading state, the application provides a more responsive and user-friendly experience, clearly indicating that an operation is underway and preventing unintended duplicate actions.

    Integrating the “Pro Model” with Stripe for Subscriptions

    The “Pro Model” component plays a key role in guiding users towards subscribing to the premium tier of the AI SaaS application. Here’s a breakdown of how it interacts with Stripe to manage subscriptions:

    1. Triggering the “Pro Model”

    The “Pro Model” component is designed to appear in two scenarios:

    • Free Trial Exhaustion: When a user attempts to use an AI tool but has exceeded their allocated free API calls, the server returns a 403 error (status code for “Forbidden”). This error triggers the onOpen function of the “Pro Model” component, prompting the user to upgrade.
    • User Initiated Upgrade: If a user proactively chooses to upgrade, clicking on an “Upgrade” button (located in the application’s sidebar) directly calls the onOpen function of the “Pro Model,” making it visible.

    2. The “Upgrade” Button and Stripe Interaction

    The “Pro Model” features an “Upgrade” button. When clicked, it triggers the following flow:

    • onSubscribe Function Execution: The button’s onClick event is bound to the onSubscribe function.
    • Loading State Activation: The onSubscribe function first sets the component’s loading state to true, disabling the button to prevent multiple clicks and visually signaling that an operation is in progress.
    • Request to Stripe Route: An Axios GET request is sent to the /api/stripe endpoint. This endpoint acts as a gateway, intelligently determining whether to initiate a new checkout session or redirect the user to the Stripe billing portal.
    • Stripe Checkout or Billing Portal:New Subscription: If the user does not have an existing Stripe customer ID associated with their account, the /api/stripe endpoint creates a Stripe checkout session using stripe.checkout.sessions.create(). This generates a checkout URL, which is sent back to the client in the response.
    • Existing Subscription: If a Stripe customer ID is found, indicating an active or past subscription, the endpoint creates a billing portal session using stripe.checkout.sessions.create(). This returns a billing portal URL.
    • Redirection: The client-side code receives the URL (either checkout or billing portal) and redirects the user’s browser window using window.location.href.

    3. Webhook Integration

    Stripe’s webhooks are essential for receiving asynchronous notifications about events related to subscriptions. The application has a dedicated /api/webhook endpoint to handle these events.

    • Checkout Session Completed: When a new checkout session is successfully completed, Stripe sends a checkout.session.completed event to the webhook endpoint. The handler extracts the user ID from the metadata object (passed during checkout session creation) and creates a new user subscription record in the database.
    • Invoice Payment Succeeded: If a user renews their subscription or an invoice payment is successful, the invoice.payment_succeeded event is triggered. The handler updates the existing user subscription record, updating the price ID and the current period end date.

    4. Visual Feedback and Error Handling

    • Loading State Deactivation: After initiating the Stripe interaction (either checkout or billing portal), the onSubscribe function sets the loading state back to false, re-enabling the “Upgrade” button.
    • Error Handling: The onSubscribe function includes a catch block to handle errors during the Stripe API call. A toast notification is displayed to the user, informing them that something went wrong.
    • Subscription Status Display: On the user’s settings page, the application uses the checkSubscription function to determine whether the user has an active and valid Pro subscription. This information is displayed to the user, informing them of their current plan status.

    By combining the “Pro Model” component, Stripe’s checkout and billing portal functionality, and webhook integration, the AI SaaS application effectively manages user subscriptions and provides a clear path for upgrading to the premium tier.

    The Role of the absoluteURL Function in the Stripe Integration

    The absoluteURL function plays a crucial role in ensuring that Stripe’s checkout and billing portal flows correctly redirect the user back to the AI SaaS application. Here’s why it’s necessary:

    1. Stripe’s Need for Absolute URLs:

    When interacting with Stripe’s checkout and billing portal, you must provide specific URLs for redirecting the user after they complete actions like subscribing or managing their subscription. Stripe requires these URLs to be absolute, meaning they include the full web address (including the protocol, domain, and path).

    Stripe needs absolute URLs because it operates as an external service. It doesn’t have knowledge of your application’s hosting environment or the base URL where it resides. Relative URLs, which only specify the path from the current location, would be meaningless to Stripe.

    2. The absoluteURL Function:

    The absoluteURL function in the sources is a utility function that constructs absolute URLs by combining:

    • The application’s base URL: This is obtained from an environment variable NEXT_PUBLIC_APP_URL. During local development, it’s set to http://localhost:3000. In production, it would point to your deployed application’s URL (e.g., https://your-ai-app.com).
    • The relative path: This is the specific path within your application where you want the user to be redirected. For example, /settings would point to the user’s settings page.

    Here’s the code for the absoluteURL function:

    export function absoluteURL(path: string) {

    return `${process.env.NEXT_PUBLIC_APP_URL}${path}`;

    }

    3. Usage in Stripe Integration:

    The absoluteURL function is used when creating Stripe checkout sessions and billing portal sessions:

    • settingsURL: The code defines a settingsURL variable using absoluteURL(‘/settings’). This ensures that when a user interacts with the Stripe checkout or billing portal, they are redirected back to the correct settings page in the AI SaaS app.
    • stripe.checkout.sessions.create() (Checkout):
    • success_url: This parameter specifies the URL where the user should be redirected after a successful subscription payment.
    • cancel_url: This parameter specifies the URL where the user should be redirected if they cancel the checkout process.
    • stripe.billingPortal.sessions.create() (Billing Portal):
    • return_url: This parameter sets the URL where the user will be returned after interacting with the billing portal (e.g., updating their payment method or canceling their subscription).

    In Summary:

    The absoluteURL function is essential for providing Stripe with complete and valid URLs, enabling correct redirection during checkout and billing portal interactions. It ensures a seamless user experience by returning users to the appropriate location within the AI SaaS application.

    Using GlobalThis.prisma to Prevent Hydration Errors

    The sources illustrate a technique for preventing hydration errors related to Prisma in a Next.js 13 development environment. The core issue stems from the way Next.js handles hot reloading during development, potentially leading to multiple instances of the PrismaClient being created, causing inconsistencies and warnings.

    Understanding the Problem:

    Every time a code change is made and Next.js performs a hot reload, there’s a risk of a new PrismaClient instance being initialized. If components rely on different PrismaClient instances, they might work with inconsistent data or encounter synchronization issues. This can lead to “hydration errors,” where the server-rendered HTML doesn’t match the client-side state after React hydration.

    The Solution: GlobalThis.prisma:

    The code snippet provided in the sources offers a way to mitigate this problem:

    // lib/prismadb.ts

    import { PrismaClient } from ‘@prisma/client’;

    declare global {

    var prisma: PrismaClient | undefined;

    }

    const prismadb = globalThis.prisma || new PrismaClient();

    if (process.env.NODE_ENV !== ‘production’) {

    globalThis.prisma = prismadb;

    }

    export default prismadb;

    Explanation:

    1. Global Variable: A global variable prisma is declared. This variable will hold a single instance of the PrismaClient.
    2. Initialization: The prismadb constant is assigned either the existing globalThis.prisma (if it exists) or a new PrismaClient instance.
    3. Development Environment Check: The code checks if the application is running in a development environment (process.env.NODE_ENV !== ‘production’).
    4. Assigning to globalThis: If in development, the prismadb instance is assigned to the global variable globalThis.prisma. This ensures that subsequent hot reloads reuse the same PrismaClient instance.

    Benefits of This Approach:

    • Single Instance: By storing the PrismaClient instance in a global variable, the code ensures that only one instance is used throughout the application, regardless of hot reloads.
    • Hydration Error Prevention: This consistency in using a single PrismaClient reduces the likelihood of hydration errors, as components are guaranteed to work with the same data and connections.
    • Development Efficiency: Developers avoid unnecessary warnings and errors related to multiple PrismaClient instances, leading to a smoother development workflow.

    Key Points:

    • The use of globalThis.prisma is specifically for development environments to handle hot reloading peculiarities.
    • In production, the globalThis assignment is skipped, allowing Prisma to manage the PrismaClient lifecycle as intended.
    • This technique helps maintain data consistency and prevent potential issues arising from multiple PrismaClient instances during development.

    Leveraging the CN Library for Dynamic Tailwind Styling

    The sources highlight the use of the CN library, imported from add/lib/utils, for managing dynamic class names in Tailwind CSS projects. Here’s why employing this library is beneficial:

    1. Conciseness and Readability:

    When dealing with conditional or dynamically generated class names, using template literals or string concatenation can become cumbersome and difficult to read. The CN library provides a cleaner and more structured approach.

    2. Tailwind-Specific Optimization:

    The CN library is specifically designed for use with Tailwind CSS. It likely leverages tools like clsx or Tailwind’s own internal merging mechanisms to efficiently combine and apply class names. This ensures optimal performance and prevents potential conflicts that might arise from manually manipulating class strings.

    3. Combining Default and Dynamic Classes:

    The sources demonstrate the CN library’s ability to seamlessly merge default Tailwind class names with dynamically generated ones. This allows for a more organized structure where base styles are defined first, followed by conditional or computed class additions.

    Example from the Sources:

    <div className={CN(“text-sm group flex p-3 w-full justify-start font-medium cursor-pointer hover:text-white hover:bg-white”,

    pathname === route.href ? “text-white bg-white/10” : “text-zinc-400”)}>

    {/* … content … */}

    </div>

    In this example, the CN function takes two arguments:

    • Default Classes: A string containing standard Tailwind classes for the <div> element.
    • Conditional Classes: A ternary operator that applies either “text-white bg-white/10” or “text-zinc-400” based on the pathname value.

    The CN library intelligently combines these classes, resulting in a single, optimized class name string that is applied to the element.

    Benefits in Summary:

    • Improved Code Clarity: The CN library makes it easier to read and understand complex styling logic involving dynamic class names.
    • Tailwind Integration: Its integration with Tailwind ensures proper merging and optimization of class names, preventing conflicts or performance issues.
    • Simplified Conditional Styling: It streamlines the process of applying conditional styles based on variables or component states.

    By adopting the CN library, developers can create more maintainable and efficient styling code when working with dynamic Tailwind class names in their Next.js 13 projects.

    Addressing Limitations of the next/image Component

    While the sources don’t explicitly detail the limitations of the next/image component, they do provide a practical example of overcoming one specific constraint. This constraint is related to the requirement of specifying allowed image domains for security and optimization purposes.

    1. The domains Property in next.config.js:

    In the context of building an image generation feature ([1, 2]), the tutorial encounters an error when attempting to display images fetched from an external source (OpenAI’s image generation API). The error message indicates that the src prop provided to the next/image component is not from a valid domain. To address this, the tutorial modifies the next.config.js file to include the following:

    // next.config.js

    module.exports = {

    // … other configurations …

    images: {

    domains: [‘oaidalleapiprodscus.blob.core.windows.net’],

    },

    };

    Explanation:

    • Security and Optimization: The next/image component enforces this restriction for security reasons and to enable image optimization techniques like lazy loading. By default, it only allows images from the same domain as the application itself.
    • Allowing External Domains: When using images from external sources, you must explicitly list the allowed domains in the domains array within the images configuration of your next.config.js file.
    • OpenAI Example: In this case, the tutorial adds the domain oaidalleapiprodscus.blob.core.windows.net to the allowed domains, as this is where the generated images are hosted by OpenAI’s API.

    2. Implications of the domains Property:

    • Security: This property acts as a whitelist, preventing the next/image component from loading images from potentially malicious or untrusted sources.
    • Performance: It enables Next.js to optimize image loading and delivery by applying techniques such as lazy loading and image resizing based on the user’s device.
    • Maintenance: As your application evolves and you integrate with different image providers, you’ll need to update the domains array to ensure that images from those sources are correctly handled.

    In Summary:

    While the tutorial doesn’t exhaustively cover all the limitations of next/image, it effectively demonstrates a common constraint and its solution:

    • Limitation: The next/image component, by default, restricts image loading to the application’s domain for security and performance reasons.
    • Solution: To use images from external sources, you must explicitly specify the allowed domains in the domains property of the images configuration within your next.config.js file.

    By understanding this configuration, you can leverage the power of the next/image component while maintaining security and optimizing image delivery in your Next.js applications.

    Preventing Free Tier Users from Exceeding API Call Limits

    The tutorial implements a robust system for managing and limiting API calls for free tier users, combining database tracking with runtime checks.

    1. Defining the Limit:

    A constant, MAX_FREE_COUNTS, is set to 5, defining the maximum number of API calls allowed for free tier users. This value can be adjusted in the constants.ts file. [1]

    2. Tracking API Usage:

    • Prisma Model: A Prisma model called userAPIlimit is created to store the API usage count for each user. [2] This model includes fields for the user’s ID (userId), their usage count (count), and timestamps for creation and updates.
    • increaseAPIlimit Function: Every time an API route is successfully called, the increaseAPIlimit function is invoked. This function checks if a userAPIlimit record exists for the current user. If it exists, the count is incremented; otherwise, a new record is created with a count of 1. [1, 3]

    3. Enforcing the Limit:

    • checkAPIlimit Function: Before executing any API request, the checkAPIlimit function is called. This function retrieves the userAPIlimit for the current user and compares the count with MAX_FREE_COUNTS. If the count is less than the limit, the function returns true, allowing the API request to proceed. Otherwise, it returns false. [3]
    • API Route Handling: Within each API route, the checkAPIlimit function determines whether the user has exceeded their free tier limit. If the limit is reached, a 403 (Forbidden) response with the message “Free trial has expired” is returned. This signals to the frontend that the user needs to upgrade to a pro plan. [4]

    4. Frontend Integration:

    • 403 Error Handling: The frontend components are designed to handle the 403 error. Upon receiving this error, a premium modal is displayed, prompting the user to upgrade their account. [5]
    • Usage Counter Display: A “Free Counter” component in the sidebar visually displays the user’s remaining free API calls (e.g., “3 / 5 Free Generations”). This counter is dynamically updated whenever an API request is made. [6-8]

    5. Subscription Management:

    • Stripe Integration: The application integrates with Stripe to handle user subscriptions and payments. Once a user subscribes, they are granted unlimited API access. [9-11]
    • checkSubscription Function: The checkSubscription function is used to determine whether a user has an active pro subscription. This function retrieves the user’s subscription information and checks if it is active and has not expired. [12]
    • Disabling Limits for Pro Users: When a user is identified as having an active pro subscription, the API call limits are disabled. The checkAPIlimit function always returns true, allowing unlimited API requests. [13]

    Overall, the tutorial provides a well-structured approach to managing API access for free tier users, leveraging Prisma for data persistence, server-side checks for enforcement, and frontend integration for user feedback and upgrade prompts.

    Handling Responses from Multiple AI Services

    The application interacts with two distinct AI service providers: OpenAI and Replicate. Each provider has its own API structure and response format, requiring specific handling within the application.

    Here’s a breakdown of how the application manages the different responses:

    1. OpenAI:

    • API Routes: The application defines dedicated API routes (/api/conversation, /api/code, /api/image) to handle requests for OpenAI services.
    • Request Formatting: OpenAI’s APIs typically require structured requests, often involving a “messages” array to simulate a conversational flow or provide context.
    • For example, in the /api/conversation route, the frontend sends an array of messages, each with a “role” (user or assistant) and “content”.
    • Similarly, the /api/code route uses an “instruction message” to set the AI’s role as a code generator.
    • Response Parsing: The API routes parse the responses from OpenAI, extracting the relevant data and transforming it into a suitable format for the frontend.
    • For /api/conversation and /api/code, the application extracts the “message” object from the response’s choices array.
    • For /api/image, the application extracts the data array, which contains image URLs, from the response.

    2. Replicate:

    • API Routes: Similar to OpenAI, dedicated API routes (/api/music, /api/video) are used for Replicate services.
    • Request Formatting: Replicate’s APIs generally have a simpler request structure, often accepting a single “prompt” string as input.
    • Response Parsing: The Replicate API routes process the responses to extract the necessary information.
    • For /api/music, the audio property is extracted from the response data.
    • For /api/video, the first item (index 0) is retrieved from the data array, representing the generated video.

    3. Frontend Handling:

    • State Management: The frontend components use React’s useState hook to manage the responses from the AI services. The specific state variable name reflects the type of response, such as messages for conversation and code, images for image generation, and music and video for their respective outputs.
    • Conditional Rendering: Based on the received data, the frontend components conditionally render different elements.
    • For conversation and code, the messages array is iterated over to display the chat history.
    • For images, the images array is used to render a grid of images.
    • For music, an <audio> element is created with the src attribute set to the music state.
    • For video, a <video> element is created with the src attribute set to the video state.

    Key Considerations:

    • Error Handling: The application includes error handling in both the API routes and frontend components. Toasts are used to display user-friendly error messages.
    • Loading States: Loading states are implemented to provide visual feedback to the user while the AI services are processing requests.
    • Data Transformation: The application often transforms the received data from the AI services into a format that is more suitable for display or further processing.

    By employing these strategies, the application effectively handles the distinct response structures and formats of OpenAI and Replicate, ensuring a seamless user experience for various AI-powered features.

    Free Tier Limitations for AI Tool Usage

    The sources outline a system for limiting free tier usage of the AI tools, specifically capping the number of times a user can make API calls to generate content. Here’s a breakdown of these limitations:

    • Maximum Free API Calls: Free tier users are restricted to a maximum of five API calls across all AI tools. This limit is defined by the MAX_FREE_COUNTS constant. [1]
    • Tracking Usage: The application utilizes Prisma, a database toolkit, to persistently track the number of API calls made by each user. Each time a user successfully triggers an AI generation, a counter associated with their account in the Prisma database is incremented. [1, 2]
    • Enforcement: Every API request is subject to a check that compares the user’s current usage count against the MAX_FREE_COUNTS limit. If the user has reached their limit, the API request is rejected with a 403 (Forbidden) error. [3]
    • Frontend Notification: Upon receiving the 403 error, the frontend displays a modal informing the user that their free trial has expired and prompts them to upgrade to a pro plan for unlimited usage. [4]
    • Visual Feedback: The application provides a visual indicator in the sidebar, displaying the user’s current usage count out of the total allowed free calls (e.g., “3 / 5 Free Generations”). This counter dynamically updates after each successful generation. [5, 6]

    Circumventing Free Tier Limitations:

    The primary method for bypassing the free tier limitations is by subscribing to a pro plan.

    • Pro Plan Benefits: A pro subscription, managed via Stripe, grants users unlimited access to all AI tools, removing the API call restrictions. [7, 8]
    • Subscription Detection: The application includes logic to detect whether a user has an active pro subscription. If a pro subscription is detected, the API usage limits are deactivated, permitting unrestricted API calls. [8]

    It’s important to note that while the free tier limitations are in place, exceeding them does not result in any charges. The application simply blocks further API requests and directs the user towards the pro subscription option.

    Understanding router.refresh in the onSubmit Function

    The code router.refresh in the onSubmit function serves a critical role in updating server components after data changes have occurred on the server. Here’s a breakdown of its significance:

    1. Context:

    • Server Components: Next.js 13 introduces the concept of server components, which primarily execute on the server-side and offer performance benefits by reducing client-side JavaScript.
    • Data Fetching: Server components often fetch data from databases or external APIs. This data needs to be synchronized with the user interface, especially after actions that modify this data.
    • onSubmit Handling: In the context of form submissions (using the onSubmit handler), data is typically sent to the server, processed, and potentially stored in a database. The frontend then needs to reflect these changes.

    2. Purpose of router.refresh:

    • Rehydration of Server Components: The router.refresh function, sourced from next/navigation, acts as a trigger to re-run server components and re-fetch data.
    • Synchronization with Server-Side Changes: After an action like submitting a form or modifying data, router.refresh ensures that all server components dependent on that data are re-executed, fetching the updated information from the server.

    3. Example in the Sources:

    • API Limits and Free Counter: The sources demonstrate the use of router.refresh to update the “Free Counter” component after each successful API call. The counter is part of a server component, and router.refresh ensures that the server component fetches the latest usage count from the Prisma database, accurately reflecting the remaining free API calls.
    • Placement in finally Block: In the onSubmit function, router.refresh is typically placed within the finally block. This placement guarantees that server components are rehydrated regardless of whether the API request succeeds or fails, ensuring consistency in the user interface.

    4. Benefits:

    • Simplified Data Synchronization: router.refresh streamlines the process of keeping the frontend in sync with server-side data changes.
    • Improved User Experience: It provides real-time feedback to the user, displaying updated data without requiring manual page refreshes.
    • Code Clarity: By explicitly using router.refresh, the intent to update server components becomes clear in the code.

    In summary, router.refresh is a powerful tool in Next.js for synchronizing server components with data changes on the server. By rehydrating server components after actions like form submissions, it ensures that the frontend displays the most up-to-date information, contributing to a smooth and responsive user experience.

    Identifying Stripe Events in the Webhook Route

    The webhook route in the sources is designed to handle events triggered by Stripe, specifically those related to managing user subscriptions. The code specifically listens for two key Stripe events:

    1. checkout.session.completed: This event is fired when a user successfully completes the checkout process for a new subscription. The webhook uses this event to create a new user subscription record in the Prisma database, linking the Stripe subscription data with the user’s ID.
    2. invoice.payment_succeeded: This event is triggered when a recurring payment for an existing subscription is successful. The webhook captures this event to update the user’s subscription information in the database, particularly the price ID and the current period end date, reflecting the renewal of their subscription.

    Detailed Breakdown of Event Handling:

    1. checkout.session.completed:

    • Data Extraction: Upon receiving this event, the webhook extracts the subscription object from the event data. This object contains detailed information about the newly created subscription.
    • Metadata Retrieval: The webhook then attempts to retrieve the userId from the metadata associated with the checkout session. This userId was originally embedded in the metadata when the checkout session was initiated on the client-side.
    • User ID Validation: If the userId is missing from the metadata, the webhook throws an error and returns a 400 (Bad Request) response, indicating that the user ID is required for processing the subscription.
    • Subscription Creation in Prisma: If the userId is present, the webhook proceeds to create a new userSubscription record in the Prisma database. It populates the record with the user’s ID, the Stripe subscription ID, the customer ID, the price ID, and the current period end date.

    2. invoice.payment_succeeded:

    • Subscription Retrieval: When this event is received, the webhook fetches the Stripe subscription using the subscription ID from the event data.
    • Subscription Update in Prisma: The webhook then locates the existing userSubscription record in the database based on the Stripe subscription ID. It updates this record with the latest price ID and the updated current period end date.

    Key Considerations:

    • Webhook Security: The webhook utilizes a signing secret provided by Stripe to verify that the incoming events are legitimate and originated from Stripe. This prevents malicious actors from spoofing events and potentially manipulating subscription data.
    • Public Route Accessibility: The webhook route is configured as a public route in the Next.js middleware, ensuring that Stripe can access it without requiring authentication. This is essential for Stripe to deliver events to the application.
    • Error Handling: The webhook includes robust error handling using a try-catch block. It returns a 400 (Bad Request) response with an error message if any issues arise during the processing of the Stripe events.

    By focusing on these two specific events, the webhook route effectively manages the creation and renewal of user subscriptions, maintaining synchronization between Stripe’s subscription data and the application’s database. This enables the application to accurately track user subscription status and enforce the limitations of the free tier.

    Enhancing Application Performance: Insights from the Sources

    The sources primarily focus on building the application’s features and do not explicitly address performance optimization techniques. However, based on the information provided and general best practices for web application performance, here are two potential avenues for improvement:

    1. Optimizing Long-Running API Calls:

    Issue: The sources highlight that certain AI models, particularly those relying on external APIs like Replicate AI for music and video generation, can have significant execution times. These long-running processes can lead to timeouts on platforms like Vercel’s Hobby plan and negatively impact user experience.

    Potential Solution: Asynchronous Processing with Webhooks

    • Background Tasks: Instead of waiting for these long-running API calls to complete within the HTTP request-response cycle, the application could delegate them to asynchronous background tasks.
    • Webhook Integration: Services like Replicate AI often offer webhooks that send notifications upon task completion. The application could leverage these webhooks to receive updates on the status of the AI generation process.
    • Frontend Updates: Upon receiving a webhook notification indicating successful generation, the application could update the frontend with the generated content.
    • Benefits: This approach prevents API requests from timing out and allows the application to remain responsive while the AI models run in the background. It also provides a mechanism for delivering real-time progress updates to the user, enhancing their experience.

    Caveats:

    • Implementing asynchronous processing requires additional infrastructure, such as a task queue and a webhook handling mechanism.
    • It introduces complexity in managing the state of AI generation tasks and synchronizing them with the frontend.

    2. Caching Frequently Accessed Data:

    Issue: The sources demonstrate that the application fetches data from various sources, including the Prisma database and the Clerk authentication service. Repeatedly fetching the same data can lead to performance bottlenecks, especially if the data is relatively static.

    Potential Solution: Implementing Caching Strategies:

    • Database Caching: Prisma supports various caching mechanisms, such as query caching and result caching. These can be implemented to reduce the number of database queries and improve response times for data that is frequently accessed but rarely changes.
    • Client-Side Caching: For data that is less dynamic, such as user profile information or static content, client-side caching using browser storage or a service worker can significantly reduce the need for repeated server requests.
    • Benefits: Caching strategies effectively reduce the load on the server and database, leading to faster response times and an overall smoother user experience.

    Caveats:

    • Carefully selecting what to cache and for how long is crucial. Caching outdated data can lead to inconsistencies and inaccuracies in the application.
    • Implementing caching mechanisms adds complexity to the codebase and requires careful consideration of cache invalidation strategies.

    Note: These recommendations are based on general performance optimization principles and may require further investigation and adaptation to the specific needs and architecture of the application.

    Ensuring Server Component Updates after API Calls

    The author utilizes the router.refresh function from next/navigation to keep server components synchronized with data changes resulting from API calls [1, 2]. This technique ensures that the frontend accurately reflects the latest server-side state without requiring manual page refreshes.

    Here’s how it works:

    1. Server Components and Data Fetching: Next.js 13 allows components to be rendered on the server for performance benefits. These server components can fetch data from APIs or databases [2].
    2. API Calls within onSubmit Function: The onSubmit function is responsible for handling form submissions. Within this function, the author makes API calls to process user input, such as sending prompts to the AI models [1, 2]. These API calls potentially update data on the server.
    3. Triggering Server Component Rehydration: To ensure the frontend reflects the updated data after an API call, the author includes router.refresh within the finally block of the onSubmit handler [1, 2].
    4. router.refresh Mechanism: router.refresh instructs Next.js to re-run the server components, effectively re-fetching data from the server [1, 2]. This process ensures that the displayed content is in sync with the latest data stored on the server.
    5. Example: API Limits and Free Counter: The author implements an API limit feature that restricts the number of free generations a user can perform [3]. After each API call, router.refresh updates the “Free Counter” component in the sidebar, accurately displaying the remaining free generations. This counter is part of a server component, and router.refresh ensures it fetches the latest usage count from the Prisma database [4].

    Benefits of router.refresh:

    • Data Synchronization: Simplifies the process of keeping the frontend aligned with server-side changes.
    • Real-Time Feedback: Offers immediate updates to users, enhancing interactivity.
    • Code Clarity: Explicitly indicates the intention to update server components.

    Placement in finally Block:

    • Guarantees server components are rehydrated whether the API call succeeds or fails [2].
    • Ensures consistency in the user interface.

    This approach ensures a seamless user experience, providing real-time feedback and maintaining data consistency between the frontend and backend.

    Managing Stripe Webhooks for Subscription Events

    The sources outline a strategy for handling Stripe webhooks specifically for events related to user subscriptions, ensuring the application’s database remains synchronized with Stripe’s records and accurately reflects the user’s subscription status. This is crucial for enforcing the limitations of the free tier and managing access to premium features. The author focuses on processing two specific events: checkout.session.completed and invoice.payment_succeeded.

    Handling checkout.session.completed Events:

    This event signifies a user’s successful completion of the checkout process for a new subscription. The webhook route designed to handle this event ([1]) performs the following actions:

    1. Subscription Retrieval: It fetches the Stripe subscription details using the subscription ID associated with the checkout session.
    2. User ID Extraction: It retrieves the userId from the metadata attached to the checkout session. Importantly, this userId was embedded in the metadata during the checkout session’s initiation on the client-side ([2]).
    3. User ID Validation: The code checks if the userId is present. If not, it returns a 400 (Bad Request) error, highlighting the requirement of a userId for associating the subscription with a specific user ([3]).
    4. Creating a New Subscription Record: When the userId is available, the webhook proceeds to create a new userSubscription entry in the Prisma database ([3]). This record links the Stripe subscription data with the user’s ID, effectively registering the user’s subscription within the application.

    Handling invoice.payment_succeeded Events:

    This event signals the successful completion of a recurring payment for an existing subscription. The webhook route handles this event to update the user’s subscription details in the database, primarily focusing on updating the price ID and the current period end date to reflect the subscription renewal ([3]). Here’s how the webhook processes this event:

    1. Fetching the Stripe Subscription: It uses the subscription ID provided in the event data to retrieve the updated subscription details from Stripe.
    2. Updating the Existing Subscription: The webhook locates the corresponding userSubscription record in the database based on the Stripe subscription ID and updates it with the latest price ID and the renewed current period end date ([3]).

    Key Considerations and Best Practices:

    • Security: The webhook implementation emphasizes security by utilizing a signing secret provided by Stripe ([1]). This secret is used to verify the authenticity of incoming webhook events, ensuring they originated from Stripe and preventing malicious actors from manipulating subscription data.
    • Public Route Accessibility: The webhook route (/api/webhook) is explicitly configured as a public route in the Next.js middleware ([4]). This configuration allows Stripe to send webhook events to the application without encountering authentication barriers, which are typically in place for routes within the application.
    • Error Handling: The webhook code includes robust error handling through a try-catch block. If any errors occur during the processing of webhook events, the route returns a 400 (Bad Request) response with an appropriate error message, aiding in debugging and providing insight into potential issues ([1]).

    By carefully managing these two specific Stripe webhook events, the author establishes a reliable mechanism for synchronizing user subscription data between Stripe and the application’s database, enabling the application to enforce its subscription model effectively.

    Please note that while the sources do not explicitly mention handling cancellation events, a robust subscription management system would typically include logic for handling customer.subscription.deleted events to reflect cancellations in the application’s database. This might involve updating the userSubscription record to mark the subscription as inactive or deleted, depending on the application’s requirements. You might want to research how to implement this functionality if you are building a similar application.

    Styling Primary Buttons and Progress Bars

    The sources provide a detailed walkthrough of building a SaaS application featuring various AI models. The author demonstrates how to style primary buttons and progress bars to enhance the application’s visual appeal and create a cohesive user experience. The styling process involves utilizing Tailwind CSS for base styles, leveraging the customization options provided by the Shadcn/UI component library, and directly modifying component source code for granular control.

    Primary Buttons: Achieving a Premium Gradient Look

    The author aims to distinguish the “Upgrade” button visually, conveying a sense of exclusivity and encouraging users to subscribe to the premium tier. This is achieved by applying a vibrant gradient background to the button.

    1. Shadcn/UI and Tailwind CSS Integration: The application relies on Shadcn/UI, a React component library built upon Radix UI and Tailwind CSS. This library provides pre-styled, accessible components that can be further customized.
    2. Creating a Custom Button Variant: The author leverages Shadcn/UI’s flexibility by introducing a new button variant named “premium” within the button.tsx component file ([1]). This variant defines the specific styles that will be applied when the variant=”premium” prop is passed to a Button component.
    3. Defining the Gradient: The premium variant utilizes Tailwind CSS classes to create a gradient background. The class bg-gradient-to-r sets a rightward linear gradient, and the from-indigo-500, via-purple-500, and to-pink-500 classes specify the gradient’s color stops ([2]).
    4. Additional Styling: The premium variant also sets the text color to white (text-white) and removes any default border (border-0) for a cleaner appearance ([2]).

    Progress Bars: Reflecting the Application’s Color Theme

    The author uses progress bars to visually represent the remaining free generations available to users. These progress bars are styled to align with the application’s overall color palette, creating a consistent and visually appealing design.

    1. Shadcn/UI’s Progress Component: The application employs the Progress component provided by Shadcn/UI, which offers basic styling and functionality out of the box.
    2. Global CSS Variables: The author sets a global CSS variable named –primary to define the primary color of the application ([3]). This variable holds an HSL color value representing a light purple shade.
    3. Inheriting the Primary Color: Shadcn/UI’s Progress component automatically inherits the value of the –primary CSS variable, applying it as the background color of the progress bar. This ensures the progress bar’s color matches the primary buttons and other elements styled using the –primary variable.
    4. Adjusting Height: The author applies the h-3 class to the Progress component to adjust its height, making it thinner for a subtle and less intrusive appearance ([4]).

    Summary

    The author styles primary buttons and progress bars by:

    • Using Tailwind CSS for base styles.
    • Creating a custom “premium” button variant with a gradient background using Tailwind CSS classes.
    • Leveraging the Progress component from Shadcn/UI and setting its color using a global CSS variable (–primary).

    This approach combines the convenience of pre-styled components with the flexibility of Tailwind CSS and direct component customization, allowing the author to achieve the desired visual aesthetic and maintain a cohesive design language throughout the application.

    ChatCNUI’s Appeal: Flexibility and Ownership

    The author highlights the choice of ChatCNUI as the CSS framework for this project, emphasizing its distinct approach compared to other popular options like Chakra UI or Material UI. ChatCNUI, according to the author, isn’t strictly a component library but rather a system that prioritizes customizability and control over the component structure.

    Here’s why the author favors ChatCNUI:

    • Accessible Component Source Code: Unlike frameworks like Material UI or Chakra UI, where components reside within the node_modules directory, ChatCNUI places its components directly within the project’s components folder [1]. This accessibility grants developers the ability to directly modify the source code of components, tailoring them to their specific needs and preferences.
    • Enhanced Customization: This direct access facilitates a deeper level of customization than what’s typically achievable with traditional component libraries [1]. Developers can freely rename elements, adjust styles, and modify the underlying logic of components to align perfectly with their project’s requirements.
    • Ownership and Flexibility: The author underscores the benefit of “complete ownership of your component system” [2]. By having the component source code readily available, developers gain a greater sense of control and can make changes without being constrained by the limitations imposed by pre-built components in other frameworks.
    • Seamless Integration with Tailwind CSS: ChatCNUI works harmoniously with Tailwind CSS, allowing developers to combine utility-first styling with customizable components [3]. This integration simplifies the process of creating a unified and visually appealing user interface.

    The author demonstrates this customization capability by modifying the destructive variant of the Button component, renaming it to Danger and showcasing how this change immediately reflects in the application’s code and user interface [2]. This example highlights the ease with which developers can adapt ChatCNUI components to their preferred terminology and styling conventions.

    While the sources don’t explicitly compare ChatCNUI to other frameworks in terms of performance or bundle size, the author’s primary rationale for choosing ChatCNUI revolves around the unparalleled flexibility and control it offers, empowering developers to shape the component system according to their project’s unique demands.

    Free API Call Limits

    The sources indicate that users of the service are granted five free API calls. The application implements a system to track and limit the usage of these free calls, prompting users to subscribe to a paid plan once they have exhausted their free quota.

    Here’s how the free API call limit is implemented:

    1. Max_free_counts Constant: A constant named Max_free_counts is defined within a constants.ts file, setting the maximum number of free calls allowed to five (). This constant serves as a central point of control for easily modifying the limit in the future.
    2. User API Limit Tracking: The application uses Prisma, an ORM (Object Relational Mapper), to interact with a MySQL database hosted on PlanetScale. A Prisma model named userAPIlimit is created to store the API call usage for each user (). This model tracks the userId, the count of API calls made, and timestamps for record creation and updates.
    3. increaseAPIlimit Utility Function: A utility function named increaseAPIlimit is responsible for incrementing a user’s API call count each time they interact with one of the AI models (). This function retrieves the user’s ID using Clerk, an authentication provider, and then either updates the existing userAPIlimit record for that user, increasing the count, or creates a new record if one doesn’t exist, initializing the count to one.
    4. checkAPIlimit Utility Function: Another utility function, checkAPIlimit, determines whether a user has reached their free call limit (). This function fetches the userAPIlimit record for the currently authenticated user and compares the recorded count against the Max_free_counts constant. If the user’s count is less than the maximum allowed or no record exists (indicating they haven’t used any calls), the function returns true, permitting access to the API. Otherwise, it returns false, signaling that the user has exhausted their free calls and should be prompted to upgrade.
    5. API Route Protection: The API routes responsible for handling requests to the AI models utilize the checkAPIlimit function to enforce the free call restriction. If a user attempts to exceed their limit, the route returns a 403 (Forbidden) error, indicating their free trial has expired (). This error triggers the display of a premium subscription modal, prompting the user to upgrade.
    6. Subscription Integration: The application integrates with Stripe, a payment processing platform, to manage subscriptions. Once a user subscribes, the checkAPIlimit function effectively bypasses the restriction, granting them unlimited access to the AI models as they are considered a paid subscriber.

    Through this mechanism, the application effectively tracks and limits free API call usage, guiding users towards subscribing to unlock unlimited access to its features.

    Integrating Customer Support with Crisp

    The sources explain how to integrate Crisp, a customer support platform, into the SaaS application. This integration provides a real-time chat interface for users to connect with support staff and receive assistance. The implementation process involves installing the Crisp SDK, configuring the Crisp chat widget, and embedding it within the application’s layout.

    Here’s a step-by-step breakdown of the integration:

    1. Crisp Account and Website ID: The first step is to create a Crisp account and obtain the Crisp Website ID. This ID, a unique identifier for the application’s Crisp integration, is essential for configuring the chat widget. The author demonstrates how to locate this ID within the Crisp dashboard and copy it for later use.
    2. Installing the Crisp SDK: The application utilizes the crisp-sdk-web package, a JavaScript SDK for interacting with the Crisp API, to implement the chat functionality. This package is installed via npm:
    3. npm install crisp-sdk-web
    4. Creating the crisp-chat Component: A dedicated React component named CrispChat is created to handle the initialization and configuration of the Crisp chat widget. This component leverages the useEffect hook to perform actions after the component renders:
    5. import { useEffect } from ‘react’;
    6. import crisp from ‘crisp-sdk-web’;
    7. export const CrispChat = () => {
    8. useEffect(() => {
    9. crisp.configure(‘<YOUR_CRISP_WEBSITE_ID>’);
    10. }, []);
    11. return null;
    12. };
    13. Within the useEffect hook:
    • crisp.configure() initializes the Crisp SDK with the Crisp Website ID obtained earlier.
    • The empty dependency array ([]) ensures this configuration runs only once when the component mounts.
    • The component returns null as it doesn’t render any visible elements; its purpose is to set up the chat functionality behind the scenes.
    1. Creating the CrispProvider Component: A CrispProvider component acts as a wrapper for the CrispChat component. This provider ensures that the Crisp chat widget is initialized within the application’s client-side environment, preventing hydration errors that can occur when server-side rendering interacts with client-side libraries:
    2. // …imports
    3. export const CrispProvider = () => {
    4. return <CrispChat />;
    5. };
    6. Embedding in the App Layout: To make the chat widget available throughout the application, the CrispProvider component is included within the main layout component (app/layout.tsx). This ensures the chat widget loads and is accessible on every page:
    7. // …imports
    8. export default function RootLayout({ children }: { children: React.ReactNode }) {
    9. return (
    10. <html>
    11. <head />
    12. <body>
    13. <CrispProvider />
    14. {/* …other layout elements */}
    15. {children}
    16. </body>
    17. </html>
    18. );
    19. }

    By following these steps, the SaaS application seamlessly integrates Crisp, providing users with a readily accessible way to communicate with support personnel for assistance. The chat widget’s appearance and behavior can be further customized within the Crisp dashboard to align with the application’s branding and user experience guidelines.

    Unlocking the Power of Genius Pro

    The sources primarily focus on building the Genius SaaS platform and its functionalities, with specific details about the Genius Pro subscription being somewhat limited. However, the available information paints a clear picture of what a Genius Pro subscription would offer:

    Unlimited AI Generations: One of the key benefits of subscribing to Genius Pro is the removal of the free API call limitations. While free users are restricted to five API calls, Genius Pro grants subscribers unlimited access to the platform’s AI capabilities (). This unrestricted access allows Pro users to leverage the various AI models without encountering usage restrictions, enabling them to fully explore the potential of Genius’s functionalities.

    Access to All AI Tools: The Genius Pro subscription presumably unlocks the full suite of AI tools available on the platform. The sources demonstrate the development and implementation of five distinct AI models:

    • Image Generation: Users can generate images from text prompts using an image generation model.
    • Video Generation: Users can create videos from text descriptions using a video generation model.
    • Conversation: Users can engage in conversations with a conversational AI model, asking questions and receiving informative responses.
    • Music Generation: Users can generate musical pieces using a music generation model, specifying desired instruments and styles.
    • Code Generation: Users can generate code snippets using a code generation model, providing descriptive instructions for the desired code functionality.

    Free users are likely limited in their access to these tools, either facing restricted usage or complete unavailability. Genius Pro subscribers, however, would have unrestricted access to all five AI models, empowering them to utilize the platform’s full creative and practical potential.

    Priority Support: While the sources don’t explicitly mention this, it’s reasonable to infer that Genius Pro subscribers might receive priority customer support. The platform integrates Crisp, a customer support platform, offering real-time chat assistance. Pro subscribers might be given preferential treatment, receiving faster responses and dedicated support channels, enhancing their overall experience and resolving any issues promptly.

    Additional Features (Possible): The sources don’t detail other potential features included in Genius Pro. However, based on common practices in SaaS platforms, additional features might include:

    • Higher Resolution Outputs: Pro subscribers could benefit from higher resolution images, videos, and audio files generated by the AI models.
    • Extended Customization Options: Pro users might have access to advanced customization settings for the AI models, allowing for greater control over the generated output.
    • Early Access to New Features: Genius Pro could provide subscribers with early access to new AI models and features, giving them an edge in leveraging the latest advancements.

    It’s important to note that these additional features are speculative and not explicitly mentioned in the sources.

    The Genius Pro subscription, by providing unlimited access to AI generations and a comprehensive suite of tools, aims to empower users with the full creative and practical capabilities of the platform. While details on specific features remain limited, the available information highlights the subscription’s focus on unlocking the full potential of Genius’s AI-powered functionalities.

    The AI Toolkit of “Genius”

    The sources provide a comprehensive overview of the development process and features of the Genius SaaS platform, highlighting the various AI tools it incorporates. These tools are designed to empower users with AI-driven capabilities for content creation and problem-solving. Here’s a detailed examination of the AI tools offered by Genius:

    • Image Generation: This tool leverages an image generation AI model, likely based on Stable Diffusion or a similar architecture, to generate images from text prompts. Users can input a descriptive phrase or sentence, such as “a horse in the Swiss Alps” [1], and the AI model processes this text to create a visually corresponding image. The application offers options to customize the number of images generated and their resolution [1], providing flexibility in tailoring the output to specific needs.
    • Video Generation: Genius also includes a video generation tool powered by a dedicated AI model. This tool enables users to transform text descriptions into short video clips. Similar to the image generation process, users provide a text prompt, such as “clownfish swimming around a coral reef” [2], and the AI model generates a video that visually represents the described scene. The sources indicate the use of the Zeroscope model hosted on Replicate, an AI model platform, for video generation [2].
    • Conversation: A conversational AI model, powered by OpenAI’s GPT-3.5-turbo [3], forms the backbone of the Genius conversation tool. This tool allows users to engage in natural language conversations with the AI, asking questions, seeking information, or simply engaging in casual dialogue. The AI model is trained on a massive dataset of text and code, enabling it to understand and respond to a wide range of prompts and questions, offering informative and contextually relevant answers.
    • Music Generation: The music generation tool in Genius leverages AI to create musical pieces from text prompts. Users can specify the desired genre, instruments, or style through text descriptions. The application utilizes the “Riffusion” model hosted on Replicate for music generation [4]. This model converts text prompts, like “piano solo” [5], into audio files, allowing users to experiment with different musical ideas and generate unique compositions.
    • Code Generation: Genius incorporates a code generation tool powered by OpenAI’s GPT-3.5-turbo model [6]. This tool assists users in generating code snippets based on descriptive instructions. Users input a text prompt outlining the desired code functionality, such as “write simple toggle button using react hooks” [7], and the AI model generates the corresponding code in a Markdown format for easy readability and integration into projects.

    These five AI tools, spanning image and video generation, conversational AI, music composition, and code generation, showcase Genius’s comprehensive approach to empowering users with AI-driven capabilities. By integrating these tools into a single platform, Genius offers a versatile toolkit for creative expression, information gathering, and technical assistance.

    Enhancing User Experience through Webhooks in the Genius Application

    The sources focus primarily on building the Genius application and implementing various functionalities, including AI models, subscription management, and customer support. However, the sources do not explicitly discuss using webhooks to enhance the user experience.

    While webhooks are not directly mentioned, the sources do provide insights into areas where webhooks could potentially be employed to improve the application’s functionality and user experience.

    For instance, the AI models, especially video and music generation, can have significant processing times. Users currently need to wait for the model to complete its operation, which can lead to a less than ideal user experience. Implementing webhooks could address this issue. Here’s a potential use case:

    • Asynchronous Processing and Notifications: A webhook could be triggered when an AI model completes its task. This webhook could then send a notification to the user, informing them that their generated content is ready. This approach would eliminate the need for users to constantly check the application for updates, improving their overall experience.

    It’s important to note that this is a hypothetical example, and the sources do not mention the actual implementation of webhooks in the Genius application.

    The sources do describe the use of Stripe webhooks for managing subscriptions and updating user data upon successful payments. This implementation showcases the potential of webhooks for handling background processes and ensuring data consistency, but it doesn’t directly impact the user experience in the same way that AI model processing notifications would.

    The Foundation of Genius’s Interface: Shadcn/ui

    The sources explicitly state that the Genius application relies on shadcn/ui for constructing its user interface. While often referred to as a component library, shadcn/ui operates differently from traditional UI frameworks like Material UI or Chakra UI [1, 2].

    Here’s a breakdown of how shadcn/ui contributes to Genius’s user interface:

    • Not a Traditional Component Library: Unlike conventional component libraries that package pre-built components within node modules, shadcn/ui functions more as a facilitator for creating and customizing components directly within the project’s codebase [1, 2].
    • Component Ownership and Modifiability: Shadcn/ui provides a foundation for building components, giving developers complete control over the code and styling. Components reside within the project’s components folder, allowing for direct modification and tailoring to the application’s specific needs [1, 2].
    • Seamless Integration with Tailwind CSS: Shadcn/ui seamlessly integrates with Tailwind CSS, a utility-first CSS framework, to provide a robust styling system. This integration enables developers to leverage Tailwind’s extensive utility classes while customizing components according to their design preferences [1, 2].
    • Flexibility and Customization: Shadcn/ui emphasizes flexibility and customization. Developers can readily rename, modify, or extend the provided components to align with the application’s visual identity and functional requirements [2].
    • CLI for Component Management: Shadcn/ui offers a command-line interface (CLI) for adding and managing components. This CLI simplifies the process of integrating new components into the project [1, 2].
    • Manual Component Addition: While the CLI streamlines component management, developers can also manually add components by copying code snippets from the shadcn/ui documentation [1].

    The sources demonstrate the use of several shadcn/ui components, including:

    • Button: Used for interactive elements like the “Generate” button for AI model prompts and the “Upgrade” button for subscription prompts [1-3].
    • Sheet: Utilized for creating a drawer-like sidebar that slides in from the side, particularly for mobile navigation [4].
    • Card: Employed for visually grouping and displaying content, such as the AI tool cards on the dashboard and the testimonials on the landing page [5, 6].
    • Progress: Used to visually represent the progress of a task, specifically the API call usage in the free tier [7].
    • Dialog: Implemented for creating modal windows, like the “Upgrade to Genius” modal triggered when a user exceeds their free API call limit [8].
    • Badge: Utilized for displaying small labels or tags, such as the “Pro” badge on the upgrade modal [9].
    • Form Field, Form Item, Form Control, Input, Select: Employed for building interactive forms for user input, like the AI model prompt forms and the subscription checkout form [10, 11].

    Shadcn/ui’s role in the Genius application extends beyond providing pre-built components. It establishes a structured approach to component development, empowering developers to build a custom UI tailored to the application’s unique requirements while leveraging the benefits of Tailwind CSS for styling.

    Tailwind CSS: The Styling Powerhouse of Genius

    The sources and the conversation history highlight that the Genius application uses Tailwind CSS for styling its user interface. Tailwind CSS is not a traditional component library; instead, it’s a utility-first CSS framework. This means it provides a vast collection of pre-defined CSS classes that developers can directly apply to HTML elements, enabling rapid UI development and customization.

    Here’s a deeper look into how Tailwind CSS shapes the Genius application’s style:

    • Utility Classes for Fine-Grained Control: Tailwind CSS offers a comprehensive set of utility classes for controlling layout, typography, colors, spacing, shadows, borders, and more. Instead of writing custom CSS rules, developers can compose these utility classes directly within the HTML, streamlining the styling process.
    • Configuration and Customization: While Tailwind CSS comes with pre-defined styles, it allows extensive customization through a tailwind.config.js file. Developers can adjust color palettes, font families, breakpoints, and other styling aspects to match the application’s design language.
    • Responsive Design Made Easy: Tailwind CSS incorporates a mobile-first approach to responsive design. Its utility classes include responsive modifiers that enable developers to tailor styles for different screen sizes, ensuring a consistent and optimal user experience across various devices.
    • Integration with Shadcn/ui: Tailwind CSS plays a crucial role in the Genius application’s integration with Shadcn/ui. Shadcn/ui provides a foundation for building components, and Tailwind CSS serves as the styling engine, providing the utility classes needed to customize the appearance of those components.

    The sources provide several examples of Tailwind CSS usage within the Genius application:

    • Layout and Spacing: Classes like flex, items-center, justify-center, space-y-4, px-4, and py-36 are used to control the arrangement and spacing of elements on the page.
    • Typography: Classes like text-4xl, font-extrabold, text-white, and text-muted-foreground are used to style text elements, adjusting font sizes, weights, and colors.
    • Colors and Backgrounds: Classes like bg-gradient-to-r, from-purple-400, to-pink-600, and text-primary are used to apply colors and gradients to elements.
    • Borders and Shadows: Classes like border, border-black/10, rounded-lg, and hover:shadow-md are used to add visual embellishments to elements, controlling borders, border-radius, and shadow effects.

    By leveraging Tailwind CSS’s extensive utility class system, the developers of the Genius application have achieved a flexible and maintainable styling solution. This approach allows for rapid UI development, easy customization, and ensures responsiveness across various devices.

    Shadcn/ui: The Building Blocks of Genius’s User Interface

    The sources and the conversation history clearly indicate that the shadcn/ui framework is used to create the UI components in the Genius application. Shadcn/ui, while often referred to as a component library, distinguishes itself from traditional UI frameworks like Material UI or Chakra UI in its approach to component creation and management.

    Here’s a detailed explanation of how shadcn/ui empowers the development of Genius’s user interface:

    • Beyond Pre-Built Components: Shadcn/ui moves away from the concept of pre-packaged components hidden within node modules. Instead, it provides a foundation for constructing components directly within the project’s codebase, giving developers greater control over their structure and appearance.
    • Component Source Code Accessibility: A key advantage of shadcn/ui is that the source code for its components resides within the project’s components folder. This accessibility empowers developers to directly modify and tailor the components to align perfectly with the application’s specific design requirements and functional nuances.
    • Synergy with Tailwind CSS: Shadcn/ui seamlessly integrates with Tailwind CSS, the utility-first CSS framework responsible for styling Genius’s interface. This integration allows developers to leverage Tailwind’s vast collection of utility classes to customize the look and feel of shadcn/ui components, achieving a consistent and maintainable styling solution.
    • Customization as a Core Principle: Flexibility and customization are at the heart of shadcn/ui. Developers have the freedom to rename, restructure, extend, or completely overhaul the provided components to match the application’s visual identity and functional needs. This adaptability ensures that the UI remains cohesive and aligned with the overall design vision.
    • CLI for Streamlined Workflow: Shadcn/ui offers a command-line interface (CLI) that simplifies the process of adding and managing components. Developers can use simple commands to integrate new components into the project, streamlining the development workflow.
    • Manual Component Integration: While the CLI facilitates component management, shadcn/ui also allows for manual component addition. Developers can copy code snippets from the shadcn/ui documentation and integrate them directly into their project, providing flexibility in how components are incorporated.

    The sources showcase the use of various shadcn/ui components within the Genius application:

    • Button: Employed for interactive elements, including buttons like “Generate,” “Upgrade,” and those within the navigation bar. [1-9]
    • Sheet: Used to create the drawer-like sidebar that slides in from the side, specifically for mobile navigation. [4, 10]
    • Card: Implemented for visually grouping and presenting content, as seen in the AI tool cards on the dashboard, the testimonial sections on the landing page, and the visual representation of tools in the upgrade modal. [11-14]
    • Progress: Utilized to visually display the progress of a task, particularly for indicating the API call usage within the free tier. [6]
    • Dialog: Employed to create modal windows, such as the “Upgrade to Genius” modal that appears when a user reaches their free API call limit. [15, 16]
    • Badge: Used to display concise labels or tags, exemplified by the “Pro” badge on the upgrade modal. [17]
    • Form-Related Components: Components like Form Field, Form Item, Form Control, Input, and Select are used extensively to construct interactive forms throughout the application, such as the AI model prompt forms and the subscription checkout form. [5, 18-20]

    Shadcn/ui’s role in the Genius application transcends merely supplying pre-built components. It provides a structured and adaptable framework for crafting a bespoke user interface tailored to the application’s distinct requirements, while seamlessly integrating with Tailwind CSS for streamlined styling. This approach fosters a balance between pre-built efficiency and customizability, allowing developers to create a visually appealing and highly functional user experience.

    A Multifaceted AI Platform: Exploring the Key Features of Genius

    The sources describe the development process of Genius, an AI-powered SaaS application offering a suite of AI tools. Let’s explore the key features that make Genius a unique and powerful platform:

    • Five Core AI Tools: Genius provides access to five distinct AI models:
    • Conversation Model: This chatbot-like tool allows users to interact with a sophisticated AI capable of answering questions, providing information, and engaging in natural language conversations.
    • Code Generation Model: This tool enables users to generate code snippets in various programming languages using descriptive text prompts.
    • Image Generation Model: This tool allows users to create images based on textual descriptions, turning their imagination into visual representations.
    • Video Generation Model: This tool empowers users to generate short videos from textual prompts, bringing dynamic visuals to life.
    • Music Generation Model: This tool allows users to create musical pieces based on descriptive prompts, exploring the realm of AI-composed music.
    • Freemium Model and Subscription Tier: Genius employs a freemium business model, offering a free tier with limited usage and a paid “Pro Plan” subscription tier.
    • Free Tier: Allows users to experiment with the platform and try out the AI models, but with restrictions on the number of generations per AI tool.
    • Pro Plan: Grants users unlimited access to all AI tools and functionalities, removing the usage restrictions of the free tier.
    • Stripe Integration for Secure Payments: Genius leverages Stripe, a widely-used payment processing platform, to handle secure and seamless subscription payments.
    • Checkout Page: Stripe’s checkout page is integrated into the application, providing a familiar and trusted experience for users making payments.
    • Subscription Management: The application includes settings for managing subscriptions, including the ability to upgrade, downgrade, or cancel the Pro Plan.
    • Customer Support via Crisp: Genius incorporates Crisp, a customer support platform, to enhance the user experience and provide assistance.
    • Real-time Chat: Crisp enables users to connect with support agents in real-time, receiving prompt assistance with any issues or inquiries.
    • User Authentication with Clerk: Genius employs Clerk for user authentication, streamlining the login and registration processes.
    • Multiple Authentication Providers: Clerk supports various authentication methods, including Google, GitHub, and email/password combinations, offering flexibility to users.
    • Secure and Seamless Login: Clerk provides a secure and streamlined login experience, allowing users to access the platform quickly.
    • User-Friendly Interface: Genius boasts a user-friendly and visually appealing interface built with modern technologies.
    • Shadcn/ui Component Library: The UI relies on Shadcn/ui, a flexible component framework that allows for customization and integration with Tailwind CSS.
    • Tailwind CSS for Styling: Tailwind CSS, a utility-first CSS framework, provides extensive pre-defined classes for styling elements and components, ensuring responsive design and a polished look.

    The sources focus primarily on the development aspects of Genius, but they showcase a well-structured and feature-rich AI platform designed for accessibility and ease of use. The combination of a freemium model, secure payment processing, integrated customer support, and a user-friendly interface makes Genius an attractive solution for individuals and businesses seeking to explore and leverage the power of AI.

    Monitoring Usage in the Freemium Model: The Role of increaseAPIlimit

    The increaseAPIlimit function plays a crucial role in managing the usage of AI tools by free tier users in the Genius application. The sources highlight that Genius operates on a freemium model, offering a free tier with limited usage and a paid Pro Plan with unlimited access. To enforce these usage limits, the application needs a mechanism to track how many times a free tier user has accessed each AI tool. This is where the increaseAPIlimit function comes in.

    Here’s a breakdown of how increaseAPIlimit contributes to managing free tier usage:

    • Tracking API Calls: Every time a free tier user makes a request to one of the AI tool APIs (e.g., conversation, code generation, image generation), the increaseAPIlimit function is invoked. This function is responsible for incrementing a counter associated with that user, essentially logging each API call.
    • User API Limit Model: To store and manage these API call counts, Genius uses a database model called userAPIlimit. Each record in this model represents a free tier user and their corresponding usage count for the AI tools.
    • Prisma ORM for Database Interactions: The sources indicate that Genius leverages Prisma, an Object-Relational Mapping (ORM) tool, to interact with the database. Prisma simplifies database operations by allowing developers to work with data using JavaScript objects and methods.
    • Steps Involved in increaseAPIlimit: The increaseAPIlimit function performs the following steps:
    1. User Identification: It first retrieves the user ID of the user making the API request. This is likely achieved using the Clerk authentication library, which handles user logins and sessions.
    2. API Limit Retrieval: The function then queries the userAPIlimit model in the database to retrieve the existing API limit count for the identified user.
    • Updating or Creating a Record:If a record already exists for the user, the function updates the count, incrementing it by one to reflect the new API call.
    • If no record is found, implying it’s the user’s first API call, the function creates a new record in the userAPIlimit model, initializing the count to one.
    • Integration with API Routes: The increaseAPIlimit function is strategically integrated into each of the API routes for the AI tools. This ensures that every time an API request is processed, the user’s usage count is updated accordingly.

    By meticulously tracking API calls, increaseAPIlimit empowers Genius to enforce usage limits on the free tier, ensuring the sustainability of the freemium model. When a user reaches the maximum allowed calls within the free tier, the application can prompt them to upgrade to the Pro Plan for unlimited access.

    This approach aligns with the broader SaaS strategy of offering a compelling free tier to attract users, while providing a clear path to a paid subscription for those seeking unrestricted access and enhanced functionalities.

    Empowering User Communication: Crisp as the Customer Support Backbone in Genius

    The sources reveal that Crisp is the technology employed to provide customer support within the Genius application. Crisp is a customer support platform designed to facilitate communication between businesses and their users.

    Here’s a detailed look at how Crisp enhances the user experience in Genius:

    • Real-time Chat Integration: Crisp’s primary functionality is its real-time chat feature. This integration enables Genius users to initiate conversations with support agents directly within the application. This immediacy in communication can be crucial for addressing user issues, answering questions, and providing guidance, ultimately enhancing user satisfaction.
    • Seamless User Experience: The integration of Crisp into Genius’s interface is designed to be unobtrusive yet easily accessible. The sources mention a Crisp icon located in the lower left corner of the application. This placement ensures that the support chat is readily available without disrupting the user’s workflow.
    • Real-time Dashboard for Support Agents: On the backend, Crisp provides support agents with a real-time dashboard that aggregates incoming user messages. This centralized view allows agents to efficiently manage conversations, track user issues, and provide timely responses.
    • Example of Crisp in Action: The sources demonstrate the use of Crisp by simulating a user reporting a problem with image generation. A message sent via Crisp is shown to immediately appear on the Crisp dashboard, highlighting the real-time nature of the communication.

    The integration of Crisp into Genius signifies a commitment to providing a supportive and user-centric experience. By offering a direct channel for communication, Genius can proactively address user concerns, gather feedback, and foster a stronger connection with its user base.

    Simplifying Secure Access: Clerk as the Authentication Gatekeeper for Genius

    The sources explicitly state that Clerk is the technology used to provide user authentication in the Genius application. Clerk is an authentication-as-a-service platform that simplifies the implementation of secure user logins and registrations, allowing developers to focus on core application features.

    Here’s a closer look at how Clerk facilitates authentication in Genius:

    • Seamless Integration with Next.js App Router: The sources emphasize that Genius is built using the app directory structure (App Router) introduced in Next.js 13. Clerk provides dedicated support for this new routing paradigm, ensuring smooth integration and functionality.
    • Multiple Authentication Providers: Clerk’s strength lies in its support for various authentication methods. Genius leverages this flexibility by enabling users to log in using their existing accounts from providers like Google and GitHub, or through traditional email/password combinations. This broadens the application’s reach and accommodates diverse user preferences.
    • Focus on Core Application Development: By using Clerk, the developer of Genius avoids the complexities of building authentication from scratch. This outsourcing of a critical but often time-consuming aspect of development allows for greater focus on building the core AI functionalities that differentiate Genius.
    • User-Friendly Interface: Clerk provides pre-built UI components, such as the SignIn and SignUp components, that streamline the authentication flow. These components are visually appealing and designed for intuitive user interaction.
    • Protection of Sensitive Routes: Clerk plays a crucial role in protecting routes within Genius that require user authentication. The sources demonstrate how Clerk’s middleware, integrated into Next.js, prevents unauthorized access to the application’s dashboard. Users are automatically redirected to the sign-in page if they attempt to access protected routes without logging in.
    • Simplified User Management: The sources highlight the use of Clerk’s UserButton component, which displays the currently logged-in user and provides options for managing their account. This component simplifies actions like signing out and potentially accessing other account-related settings.

    In summary, Clerk acts as a robust and user-friendly authentication layer within Genius. By handling the complexities of user management, Clerk frees up the developer to concentrate on delivering a seamless and secure experience for users interacting with the platform’s diverse set of AI tools.

    A Synergy of Modern Technologies: Constructing the Front-End of Genius

    The sources provide a detailed walkthrough of building the Genius application, focusing primarily on the back-end logic and API integrations. While they don’t explicitly name a single primary technology for the front-end, they do highlight the use of several key technologies working in synergy to construct the user interface:

    • Next.js 13: Next.js serves as the foundational framework for the entire Genius application, encompassing both the front-end and back-end. Next.js is a React-based framework that offers server-side rendering, static site generation, built-in routing, and other features that streamline web development.
    • App Router (app Directory): The sources emphasize the use of the new app directory structure in Next.js 13, often referred to as the App Router. This structure provides enhanced features for nested routing, layouts, server components, and improved performance.
    • Server Components: The sources demonstrate the use of server components within Genius. Server components execute on the server, allowing for direct data fetching from databases and APIs without the need for client-side hydration, often resulting in faster initial page loads and improved SEO.
    • Client Components: Genius also utilizes client components, which run in the user’s browser and are responsible for interactivity and dynamic updates. Client components are used for elements like forms, buttons, and real-time updates to the user interface.
    • React: As a React-based framework, Next.js leverages React, a JavaScript library for building user interfaces. React’s component-based architecture enables developers to break down complex UIs into smaller, reusable pieces, making development more organized and maintainable.
    • Shadcn/ui Component Library: Shadcn/ui emerges as a central player in styling the Genius front-end. Shadcn/ui is a component library built on top of Tailwind CSS, providing a collection of pre-designed, customizable, and accessible components.
    • Flexibility and Customization: Shadcn/ui components offer a high degree of flexibility, allowing developers to tailor their appearance and behavior using props and Tailwind CSS classes. This is in contrast to some component libraries that provide more rigid, pre-styled components.
    • Direct Access to Component Code: A notable advantage of Shadcn/ui highlighted in the sources is its approach to component management. Unlike some component libraries that hide component code within node_modules, Shadcn/ui places the component code directly within the project’s components folder. This grants developers complete control over the appearance and behavior of components, enabling deep customization and modifications.
    • Tailwind CSS: Tailwind CSS is a utility-first CSS framework that provides a vast set of pre-defined CSS classes. These classes can be directly applied to HTML elements, streamlining styling and eliminating the need for writing custom CSS in many cases.
    • Integration with Shadcn/ui: The sources showcase how Shadcn/ui seamlessly integrates with Tailwind CSS, allowing developers to combine pre-designed components with the flexibility and convenience of Tailwind’s utility classes.
    • Responsive Design: Tailwind’s responsive modifiers (e.g., sm, md, lg) enable developers to create user interfaces that adapt smoothly to different screen sizes, ensuring an optimal experience on desktops, tablets, and mobile devices.
    • Lucid React Icon Library: For incorporating icons into the user interface, Genius employs Lucid React, an icon library providing a wide range of scalable vector icons. These icons enhance the visual appeal and clarity of the application’s UI.
    • Typewriter Effect Library: The sources showcase the use of the Typewriter Effect library to create animated text that simulates typing. This effect is employed on the landing page to draw attention to the application’s key features.
    • Clerk UI Components: Clerk, the authentication provider, offers pre-built UI components like SignIn, SignUp, and UserButton. These components simplify the integration of authentication flows and user management features into the front-end.

    In conclusion, the Genius application’s front-end is a well-crafted combination of modern technologies. Next.js forms the framework, React provides the component-based structure, Shadcn/ui contributes styled and customizable components, Tailwind CSS empowers styling, and additional libraries like Lucid React and Typewriter Effect add visual flair and interactivity. The developer’s choice to leverage Shadcn/ui’s direct access to component code demonstrates a preference for control and flexibility in shaping the application’s look and feel.

    Shaping the Code Generator’s Behavior: The Role of the “Instruction Message”

    The sources provide a clear explanation of the purpose of the “instruction message” in the code generation API route within the Genius application. This message acts as a guiding force, shaping the behavior of the OpenAI language model (GPT-3.5-turbo) responsible for generating code snippets.

    Here’s a breakdown of the instruction message’s role:

    • Specifying the AI’s Role: The instruction message, with a role of “system,” explicitly defines the AI’s purpose within the code generation context. The message:
    • {
    • role: “system”,
    • content: “You are a code generator. You must answer only in markdown code snippets. Use code comments for explanations.”
    • }
    • informs the model that its primary function is to generate code, not engage in general conversation or provide information unrelated to coding tasks. [1]
    • Output Format Control: A crucial aspect of the instruction message is its directive regarding output format. The message instructs the AI to:
    • Provide responses exclusively in markdown code snippets. This ensures that the generated code is presented in a structured and readable format, suitable for direct use or easy integration into code editors.
    • Use code comments for explanations. This encourages the model to provide clarity and context for the generated code, making it more understandable for developers who might be using or adapting it. [1]
    • Demonstrating the Impact: The sources showcase the impact of the instruction message through a comparison of responses from the code generation and conversation models.
    • When asked “What is your purpose?,” the code generation model, primed with the instruction message, responds with a clear statement of its coding-centric role. [1]
    • In contrast, the conversation model, lacking the instruction message, provides a more general response, highlighting its broader purpose of assisting with information and tasks. [1]

    The inclusion of the instruction message is a strategic move to fine-tune the AI’s behavior. It transforms a general-purpose language model into a specialized code generation tool, ensuring that responses align with user expectations within the code generation context. This approach enhances the user experience, providing code snippets in a readily usable format and with helpful explanations embedded within the code itself.

    The Sentinel of Free Trials: Error Code 403 Guards the API Gate

    The sources provide a very detailed explanation of how the Genius application enforces limits on free tier usage, but they don’t explicitly specify an “error code” in the conventional sense. However, they do highlight the use of HTTP status code 403 (Forbidden) to signal that a user has exhausted their allotted free API calls.

    Here’s how this mechanism works within Genius:

    • Tracking API Usage: The application utilizes a database table called user_api_limits to keep track of each user’s API call count. This table stores the user’s ID and an integer representing the number of API calls they’ve made.
    • Enforcing the Limit: In each of the API routes (conversation, code, image, music, video), there’s logic that checks if the user is on a free trial and if they’ve exceeded the maximum allowed free calls (set to 5 in the provided code).
    • The 403 Response: If a free trial user attempts to make an API call beyond their limit, the server responds with a NextResponse object containing the message “Free trial has expired” and, crucially, an HTTP status code of 403.
    • Front-End Handling: On the front-end, the application specifically looks for this 403 status code to determine if the user needs to be prompted to upgrade to a paid subscription. If a 403 response is received, a modal window appears, encouraging the user to subscribe.

    Therefore, while not a traditional “error code” in the context of software exceptions or internal error handling, HTTP status code 403 serves as the signal that a user’s free trial has ended. This status code is a standard HTTP response indicating that the server understood the request but refuses to authorize it, fitting the scenario where a user has exceeded their free tier limits.

    The use of HTTP status codes in this way is a common practice in web applications to communicate the outcome of requests between the server and client.

    Taming Hydration Errors: A Strategic Approach in React

    While the sources do not directly address general strategies for resolving hydration errors in React, they do showcase a specific technique used to fix a hydration error within the Genius application’s MobileSidebar component. This technique, while not universally applicable to all hydration errors, offers valuable insights into how developers can approach these issues.

    Understanding the Root of the Problem

    Hydration errors occur when the HTML rendered on the server (during Server-Side Rendering or Static Site Generation) does not match the structure that React expects to find on the client-side during hydration. This mismatch can lead to unpredictable behavior and errors in the user interface.

    The MobileSidebar Case

    The specific hydration error encountered in the MobileSidebar component stemmed from the component’s initial rendering logic. The component relied on a state variable, isMounted, which was initially set to false. This meant that on the server, the component would render a different structure compared to the client, where isMounted would eventually become true.

    Solution: Conditional Rendering with isMounted

    To resolve this mismatch, the developers introduced a conditional rendering check within the MobileSidebar component. The code:

    if (!isMounted) return null;

    ensures that the component renders nothing (null) on the server, where isMounted is initially false. This aligns the server-rendered HTML with the initial state on the client, preventing the hydration error.

    Key Concept: Aligning Server and Client States

    The core principle behind this fix is to ensure that the initial state of the component on the server matches the state on the client during hydration. By conditionally rendering the component based on the isMounted state, the developers avoided the mismatch that was causing the hydration error.

    Beyond isMounted: Broader Considerations

    It’s important to note that while this technique worked effectively for the MobileSidebar component, it is not a one-size-fits-all solution for hydration errors. Resolving hydration errors often requires careful analysis to identify the root cause of the mismatch between the server and client.

    Some common causes of hydration errors and potential approaches to address them include:

    • Data Fetching: When data is fetched on the client-side after initial render, it can lead to changes in the component’s structure, causing a mismatch with the server-rendered HTML. Strategies include:
    • Fetching data on the server-side (if possible) and passing it as props to the component.
    • Using placeholder content or loading states until the data is fetched on the client.
    • Third-Party Libraries: Some third-party libraries may have side effects or rely on browser-specific APIs that are not available during server-side rendering. Solutions involve:
    • Initializing such libraries only on the client-side, using conditional logic.
    • Finding alternative libraries that are server-side rendering compatible.
    • Global State Management: If a component relies on global state that is not synchronized between the server and client, it can lead to hydration errors. Approaches include:
    • Initializing the global state on the server-side and passing it to the client.
    • Using server-side rendering compatible state management libraries or techniques.
    • DOM Manipulation: Direct manipulation of the DOM outside of React’s lifecycle methods can interfere with hydration. The recommendation is to:
    • Use React’s built-in mechanisms for DOM manipulation (e.g., refs).

    General Tips for Debugging Hydration Errors

    • Inspect the Error Message: React typically provides helpful error messages that pinpoint the location and potential cause of the hydration issue.
    • Console Logging: Strategically placing console.log statements within the component’s lifecycle methods can help track state changes and identify discrepancies between the server and client.
    • React Developer Tools: The React Developer Tools browser extension is invaluable for inspecting the component tree, props, and state, aiding in the identification of hydration mismatches.

    A Final Note

    Hydration errors can be tricky to debug, but with a systematic approach and a clear understanding of the potential causes, developers can effectively resolve these issues and ensure a smooth and consistent user experience. Remember that the key is to align the initial state of the component on the server with the state on the client.

    Guardian of the Premium Realm: The checkSubscription Function

    The checkSubscription function plays a crucial role in the Genius application, acting as the gatekeeper to premium features that are reserved for paid subscribers. Its purpose is to determine whether a user has an active and valid subscription, allowing or restricting access to certain functionalities based on this subscription status.

    Let’s break down the function’s logic and its implications within the application:

    • Retrieving User Subscription: The function begins by retrieving the user’s ID from the Clerk authentication system. If a user ID is found, it queries the database to fetch the user’s subscription details from the user_subscriptions table. This table stores information about a user’s subscription, including their Stripe customer ID, subscription ID, price ID, and the current subscription period end date.
    • Validating Subscription: The function then performs two crucial checks to validate the subscription:
    • Existence: First, it checks if a subscription record exists for the user. If no record is found, it implies the user is not subscribed, and the function returns false.
    • Validity: Second, if a subscription record is found, the function verifies its validity by checking if the current period end date, plus a one-day grace period, is greater than the current date. This grace period is a buffer to accommodate potential slight discrepancies in time calculations and provide a smoother user experience. If the subscription is expired, the function returns false.
    • Guiding Access Control: The boolean value returned by checkSubscription (true for active and valid subscriptions, false otherwise) is used throughout the application to control access to features. For example, in the API routes that handle AI generations (conversation, code, image, music, video), the checkSubscription function is called to determine whether to allow a user to proceed with their request or to trigger the “Upgrade to Genius Pro” modal.
    • UI Elements: The function also influences the display of UI elements. For instance, in the sidebar, the free generation counter is hidden if the user has an active subscription. Similarly, in the settings page, the subscription button’s text changes from “Upgrade” to “Manage Subscription” depending on the subscription status.

    Key Takeaway:

    The checkSubscription function serves as the central authority for managing subscription status within the Genius application. It encapsulates the logic for retrieving and validating a user’s subscription, providing a single source of truth that guides access control and UI adjustments based on subscription status. This approach promotes code modularity and ensures a consistent user experience, clearly differentiating between features available to free and paid users.

    Building Complete Links: The Role of the absoluteURL Function

    The absoluteURL function serves a critical purpose within the Genius application, particularly in the context of integrating with Stripe for subscription management. Its role is to generate complete, absolute URLs that are required by Stripe for seamless redirection and communication during the checkout and billing portal processes.

    Understanding the Need for Absolute URLs

    Stripe, as a third-party payment processing platform, interacts with your application through webhooks and redirects. For these interactions to function correctly, Stripe needs URLs that are fully qualified—meaning they include the protocol (e.g., https://), the domain name, and the path. This is in contrast to relative URLs, which only specify the path relative to the current page.

    Inside the absoluteURL Function

    The code for the absoluteURL function is simple yet effective:

    export function absoluteURL(path: string): string {

    return `${process.env.NEXT_PUBLIC_APP_URL}${path}`;

    }

    Let’s break down how it works:

    1. Retrieving the Base URL: The function first accesses an environment variable named NEXT_PUBLIC_APP_URL. This environment variable is expected to hold the base URL of the deployed application. For local development, this is typically set to http://localhost:3000. For a production deployment, it would be the actual domain name of your application (e.g., https://genius-app.com).
    2. Appending the Path: The function then takes the input path (which represents the relative path of the desired URL) and appends it to the base URL retrieved from the environment variable. The use of template literals (backticks) allows for easy string interpolation.

    Example Usage

    Let’s consider an example where you want to redirect the user to the settings page (/settings) after they complete the Stripe checkout process. Using the absoluteURL function, you would call it like this:

    const settingsURL = absoluteURL(‘/settings’);

    Assuming NEXT_PUBLIC_APP_URL is set to https://genius-app.com, the settingsURL variable would now contain the string “https://genius-app.com/settings&#8221;. This complete URL can then be passed to Stripe’s API during checkout session creation.

    Importance for Stripe Integration

    The use of the absoluteURL function is crucial for the following reasons:

    • Stripe Requirements: Stripe’s API, specifically for creating checkout sessions and billing portal sessions, mandates the use of absolute URLs for redirects. Relative URLs would not work, as Stripe needs to know the complete address to redirect to.
    • Environment Awareness: By relying on an environment variable for the base URL, the absoluteURL function adapts to different environments (development, staging, production) without requiring code modifications. This promotes maintainability and reduces the risk of errors when deploying to different environments.
    • Correct Redirection: Without using the absoluteURL function, Stripe might not be able to redirect the user back to your application correctly after completing a checkout or interacting with the billing portal. This would lead to a broken user experience and potentially lost subscriptions.

    In Summary:

    The absoluteURL function ensures that complete and correct URLs are used when interacting with Stripe, preventing redirection failures and enabling a smooth subscription management flow for Genius users. By abstracting the base URL into an environment variable, the function remains flexible and adaptable to different deployment scenarios.

    Styling Synergy: The Significance of the CN Library with Tailwind CSS

    The sources showcase a specific coding practice that highlights the synergy between Tailwind CSS and a utility library referred to as the CN library. While the sources don’t explicitly name the library, based on the provided code snippets and the context of Tailwind CSS usage, it is highly likely that the CN library refers to either the clsx library or the tailwind-merge library. Both libraries are popular choices within the Tailwind CSS ecosystem for enhancing class name management.

    Let’s break down the significance of using the CN library (assuming clsx or tailwind-merge) alongside Tailwind CSS:

    1. Streamlining Dynamic Class Names

    Tailwind CSS encourages the use of utility classes directly in your HTML markup. This approach leads to very readable and maintainable code, especially for static styles. However, when you need to apply styles dynamically based on conditions or component states, managing class names within HTML can become cumbersome.

    The CN library elegantly addresses this challenge. It provides a function that accepts an arbitrary number of arguments, each representing a potential class name. These arguments can be strings (for static Tailwind classes) or expressions that evaluate to either a string or false. The CN function intelligently merges these arguments, filtering out any falsy values, and returns a single, space-separated string of class names.

    2. Code Readability and Maintainability

    Imagine a scenario where you have a button component that needs to change its background color based on its state (e.g., active, disabled). Without a utility like CN, you might end up with conditional logic directly within your class name attribute, leading to lengthy and potentially hard-to-read markup:

    <button

    class={

    isActive ? ‘bg-blue-500 hover:bg-blue-700’ :

    isDisabled ? ‘bg-gray-300 cursor-not-allowed’ :

    ‘bg-blue-500 hover:bg-blue-700’

    }

    >

    Button

    </button>

    Using the CN library, this logic becomes significantly cleaner:

    import cn from ‘clsx’;

    <button

    class={cn(

    ‘bg-blue-500 hover:bg-blue-700’,

    isActive && ‘active-style’,

    isDisabled && ‘disabled-style’

    )}

    >

    Button

    </button>

    This approach separates the dynamic class logic from the static Tailwind classes, making the code more readable, maintainable, and easier to reason about.

    3. Avoiding Class Name Conflicts

    Tailwind CSS generates a vast number of utility classes. While this offers incredible flexibility, it also increases the potential for accidental class name collisions, especially when working with dynamic styles.

    The CN library helps mitigate this risk by providing a structured and predictable way to merge class names. It ensures that only valid class names are included in the final output, preventing unexpected behavior caused by conflicting styles.

    4. Optimizations (tailwind-merge)

    If the CN library specifically refers to tailwind-merge, there’s an additional layer of significance. tailwind-merge is built to optimize the final output of class names. It’s aware of the structure and hierarchy of Tailwind’s utility classes and intelligently merges them to minimize the resulting HTML size. This optimization can lead to performance improvements, particularly for larger applications.

    5. Integration with React Hook Form

    The sources demonstrate the use of the CN library within a React Hook Form setup. React Hook Form is a popular library for managing forms in React. It provides convenient ways to handle form state, validation, and submission. When combined with the CN library, it becomes straightforward to apply dynamic styles to form elements based on their validation status or other conditions managed by React Hook Form.

    Examples from the Sources

    The sources provide several instances where the CN library enhances class name management:

    • Sidebar Styling: In the sidebar.tsx component, the CN library is used to dynamically style the sidebar links based on the current route. This ensures that the active link is visually highlighted, providing clear navigation feedback to the user [1].
    • Heading Component: The heading.tsx component uses the CN library to apply styles to an icon container, merging static Tailwind classes with a dynamically determined background color [2].
    • Message Styling: When rendering messages, the CN library is used to differentiate the appearance of user messages and AI-generated messages [3].

    Conclusion

    The CN library, whether it’s clsx or tailwind-merge, proves to be a valuable asset when using Tailwind CSS. It streamlines dynamic class name management, improves code readability, helps avoid conflicts, and can potentially optimize the final output for better performance. Its integration with React Hook Form further enhances its utility for managing form element styles. By embracing these tools, developers can leverage the full power of Tailwind CSS while maintaining a clean and organized codebase.

    Prisma’s Role in Enforcing API Limits for Free Users

    The sources describe the development of an application with multiple AI-powered features, offering both free and paid tiers. The Prisma library is central to implementing API limits, ensuring free users can only access these features a limited number of times before needing to subscribe. Here’s a breakdown of its role:

    1. Defining the Limit Model:

    • In the schema.prisma file, a user_api_limit model is defined using Prisma’s schema definition language. [1]
    • This model includes fields to track the user ID (user_id), the number of times they’ve used the API (count), and timestamps for creation and updates (created_at and updated_at). [1]
    • This schema acts as the blueprint for a table in the PlanetScale database, which Prisma will manage. [2]

    2. Tracking API Usage:

    • Whenever a free user successfully uses an AI feature, the increase_api_limit function is invoked. [3, 4]
    • This function uses Prisma Client (Prisma_db) to interact with the database. It first checks if a user_api_limit record exists for the user. [5]
    • If a record exists, the count field is incremented using an update operation. [5]
    • If no record is found, a new one is created with a count of 1, indicating the user’s first API call. [5]

    3. Enforcing the Limit:

    • Before each API call, the check_api_limit function is called to determine if the user has exceeded their free usage. [4]
    • This function fetches the user’s user_api_limit record using Prisma_db. [4]
    • It compares the count with a predefined max_free_counts constant (set to 5 in the example). [3, 4]
    • If the count is less than the limit, the function returns true, allowing the API call. [4]
    • If the limit is reached, the function returns false. The API route then responds with a 403 error (“free trial has expired”), triggering the “Upgrade to Genius Pro” modal on the front end. [4, 6]

    4. Visualizing Usage in Prisma Studio:

    • The sources mention using npx prisma studio to launch Prisma Studio, a visual interface for interacting with the database. [1, 4]
    • This tool allows developers to view and manipulate data, including the user_api_limit records, providing a way to monitor free user usage. [1, 4]

    In essence, Prisma acts as the bridge between the application logic and the database:

    • It provides a convenient way to define the data model for tracking API usage.
    • Its client library (Prisma_db) offers functions to query, update, and create records, abstracting away complex database interactions.
    • This enables efficient tracking of free user API calls and enforcement of limits, guiding users to subscribe for unlimited access.

    Capturing and Processing User Input for Code Generation

    The sources provide a detailed walkthrough of building a code generation tool within a larger AI application. Let’s examine the method used to handle user input in this specific implementation:

    1. The Input Form:

    • The user interface for code generation features a text input field, allowing users to provide a description of the code they wish to generate.
    • The input field is managed using the react-hook-form library, which provides structure and validation capabilities.

    2. Schema Validation:

    • A schema is defined using the zod library to ensure the user input conforms to the expected format.
    • In the provided example, the schema specifies that the input (named “prompt”) must be a string with a minimum length of one character.
    • This validation step helps prevent errors and ensures the input is suitable for processing by the code generation model.

    3. Submission Handling:

    • When the user submits the form, the onSubmit function, defined within the code page component, is triggered.
    • The onSubmit function receives the validated input values from react-hook-form.

    4. Preparing the API Request:

    • The input prompt is packaged into a request object to be sent to an API route responsible for code generation.
    • This route, located at /api/code, handles the interaction with the underlying code generation model, which is powered by OpenAI.

    5. Sending the Request:

    • The request object is sent to the /api/code route using an HTTP request, likely facilitated by the axios library, a popular choice for making API calls in JavaScript applications.

    6. Server-Side Processing:

    • The /api/code route receives the request and extracts the user’s prompt.
    • The prompt, along with a pre-defined instruction message, is sent to the OpenAI API to generate the code.
    • The instruction message guides the OpenAI model, specifying that it should act as a “code generator” and provide responses in the form of markdown code snippets with comments for explanations.

    7. Response Handling:

    • The code generated by the OpenAI model is returned to the client-side application as part of the API response.

    8. Displaying the Generated Code:

    • The client-side application receives the code snippet and displays it to the user.
    • The react-markdown library is used to render the markdown content, ensuring proper formatting of the code and comments.
    • Additional styling is applied using Tailwind CSS classes to enhance the visual presentation of the code.

    In summary, the method for handling user input for code generation involves:

    • Collecting Input: Using a form with react-hook-form for structure and validation.
    • API Communication: Sending the input to an API route for processing by the code generation model (OpenAI).
    • Code Display: Rendering the generated code using react-markdown and applying styles with Tailwind CSS.

    This process effectively bridges the gap between user intent and AI-powered code generation, providing a user-friendly interface and a structured backend to produce code snippets based on natural language descriptions.

    Managing the Loading State during Code Generation

    The sources provide a detailed illustration of how loading states are managed during code generation requests, ensuring a smooth user experience while the application interacts with the OpenAI API. Here’s a comprehensive explanation based on the source code and our previous conversation:

    1. Initializing the Loading State:

    • In the code page component (likely named code.tsx), a state variable isLoading is introduced using the useState hook from React. It’s initialized to false, indicating that no code generation request is in progress.

    2. Triggering the Loading State:

    • When the user submits the code generation request, the onSubmit function is invoked. Inside the try block of this function, the setLoading function (paired with the isLoading state) is called with true to signal the start of the code generation process.

    3. Displaying a Loading Indicator:

    • A conditional rendering mechanism is implemented to display a loading indicator while isLoading is true.
    • This indicator could be a simple text message (“Genius is thinking…”) or a more visually engaging animation. The sources showcase the creation of a Loader component, which is likely used for this purpose.

    4. Sending the API Request:

    • While the loading indicator is visible, the application concurrently sends the code generation request to the /api/code route. This is an asynchronous operation, allowing the user interface to remain responsive and provide feedback to the user.

    5. Handling the Response:

    • Once the /api/code route completes the interaction with the OpenAI API and returns a response, the onSubmit function’s try block continues execution.

    6. Resetting the Loading State:

    • Inside a finally block within the onSubmit function, the setLoading function is called with false to reset the loading state, regardless of whether the code generation was successful or encountered an error. This ensures that the loading indicator is hidden and the user interface returns to its normal state.

    7. Displaying the Result or Error:

    • Based on the response from the /api/code route, the application either displays the generated code snippet or handles any errors that occurred during the process. This might involve showing an error message to the user or initiating other appropriate actions.

    Code Snippet Illustration:

    const [isLoading, setLoading] = useState(false);

    const onSubmit = async (values) => {

    try {

    setLoading(true); // Start loading

    const response = await axios.post(‘/api/code’, values);

    // … handle response, display code snippet

    } catch (error) {

    // … handle error

    } finally {

    setLoading(false); // Stop loading

    }

    };

    Key Takeaways:

    • The loading state management is crucial for providing a seamless user experience during asynchronous operations like code generation.
    • The use of useState and conditional rendering allows the application to dynamically display a loading indicator while the request is being processed.
    • The finally block ensures that the loading state is always reset, preventing the indicator from getting stuck in the loading state if an error occurs.

    Distinguishing User and AI Messages in the UI

    The sources offer a detailed guide to constructing a conversational AI application. While they don’t explicitly detail the styling of user versus AI messages, they provide enough clues to infer a potential approach:

    1. Message Structure:

    • The conversation history is stored in a messages array, where each message is an object with properties like role (either “user” or “assistant”) and content.

    2. Dynamic Styling with CN:

    • The sources demonstrate using a utility function CN (likely a custom wrapper around the classnames library) to dynamically apply Tailwind CSS classes based on conditions.

    3. Background Color Differentiation:

    • Based on the code snippet for styling messages, it can be inferred that user messages are given a white background (bg-white) with a subtle border, while AI (assistant) messages have a muted background (bg-muted).

    4. Potential Additional Styling:

    • While not explicitly mentioned, it’s common to further differentiate user and AI messages visually. Possibilities include:
    • Text alignment: Aligning user messages to the right and AI messages to the left.
    • Avatar icons: Displaying distinct avatars next to each message type, as hinted at by the creation of userAvatar and botAvatar components.
    • Font variations: Subtle differences in font weight or style could be applied.

    Code Snippet Illustrating the Approach:

    messages.map((message) => (

    <div

    key={message.content}

    className={CN(

    “p-8 w-full flex items-start gap-x-8 rounded-lg”,

    {

    “bg-white border border-black/10”: message.role === “user”,

    “bg-muted”: message.role !== “user”,

    }

    )}

    >

    {/* Avatar Icon */}

    {message.role === “user” ? <UserAvatar /> : <BotAvatar />}

    {/* Message Content */}

    <p className=”text-sm”>{message.content}</p>

    </div>

    ));

    Inferred Visual Distinction:

    Based on the available information, it’s likely that user messages appear with a white background and a border, while AI messages have a muted background. Additional visual distinctions, like text alignment or avatar icons, are not explicitly described but are common practices in chat interfaces and hinted at in the source code.

    Highlighting the Active Page in the Sidebar Navigation

    The sources provide a step-by-step guide on constructing an AI application with a sidebar navigation menu. They demonstrate a clear method for dynamically applying a class name to the active page’s link to visually highlight it.

    1. Identifying the Current Route:

    • Within the sidebar.tsx component, the usePathname hook from the next/navigation library is used to determine the current route (URL path) of the application.
    • This hook returns a string representing the pathname, which is then stored in the pathname constant.

    2. Route Configuration:

    • An array named routes stores the configuration for each sidebar link.
    • Each object in the routes array contains properties such as label, icon, href (the target URL), and color (for styling the icon).

    3. Mapping Routes to Links:

    • The routes array is iterated over using the map function to generate the link elements for the sidebar navigation.

    4. Conditional Class Application with CN:

    • The CN utility function (likely based on classnames) is employed to dynamically apply Tailwind CSS classes based on a condition.

    5. The Highlighting Condition:

    • For each link, the CN function evaluates whether the pathname (current route) matches the href property of the current route object from the routes array.
    • If the paths match, indicating the link represents the active page, the CN function applies the classes text-white and bg-white/10 to give the link a highlighted appearance (white text with a semi-transparent white background).
    • If the paths don’t match, the link is styled with a less prominent gray color (text-zinc-400).

    Code Snippet Illustrating the Technique:

    const pathname = usePathname();

    // …

    routes.map((route) => (

    <Link key={route.href} href={route.href}>

    <div

    className={CN(

    // Default classes

    “text-sm group flex padding-3 w-full justify-start font-medium cursor-pointer hover:text-white hover:bg-white/10 rounded-lg transition”,

    // Conditional class for active link

    pathname === route.href ? “text-white bg-white/10” : “text-zinc-400”

    )}

    >

    {/* Icon and Label rendering */}

    </div>

    </Link>

    ));

    In Conclusion:

    This method effectively leverages the usePathname hook, the CN utility function, and conditional logic to dynamically style the active sidebar link based on the current route, providing a clear visual indication of the user’s location within the application.

    Strategies to Prevent Server-Side Rendering and Hydration Mismatches

    The sources primarily focus on building an AI SaaS application using Next.js, OpenAI, and other technologies. While they don’t explicitly detail comprehensive strategies for preventing all server-side rendering (SSR) and hydration errors, they do showcase specific techniques and offer insights into potential causes and solutions for these issues.

    1. Understanding the Challenge

    Hydration in Next.js involves the process of “attaching” JavaScript behavior to the server-rendered HTML. Mismatches occur when the client-side JavaScript generates a different DOM structure or state than what was initially rendered on the server. This can lead to unexpected behavior, visual inconsistencies, and even application errors.

    2. Techniques Employed in the Sources

    a) Using useEffect for Client-Side Initialization:

    • In components like FreeCounter, the sources demonstrate the use of React’s useEffect hook to perform actions only after the component has mounted in the browser. This prevents code that relies on browser APIs (like window or document) from running on the server, where those APIs are not available.

    // FreeCounter.tsx (simplified)

    ‘use client’;

    export const FreeCounter = ({ apiLimitCount }) => {

    const [mounted, setMounted] = useState(false);

    useEffect(() => {

    setMounted(true);

    }, []);

    if (!mounted) return null; // Avoid rendering on the server

    // … rest of the component logic

    };

    b) The use client Directive:

    • The sources consistently use the ‘use client’ directive at the top of client-side components. This explicitly instructs Next.js to treat these components as client-only, preventing them from being rendered on the server. This is crucial for components that rely on browser-specific functionality or interact with the DOM in ways that could lead to hydration mismatches.

    c) Conditional Rendering with isMounted State:

    • Components like FreeCounter use a state variable (isMounted) to track whether the component has mounted in the browser. By conditionally rendering content based on this state, they ensure that server-side rendering produces a minimal, non-interactive version of the component, preventing potential hydration errors caused by client-side logic executing prematurely.

    3. Potential Areas for Improvement

    The sources, while demonstrating good practices, could be enhanced with a more comprehensive error-handling strategy and explicit checks for potential hydration mismatches. Here are some areas to consider:

    a) Robust Error Handling:

    • Implementing more robust error handling within try…catch blocks can help catch and gracefully handle unexpected situations during rendering. For example, catching errors related to API requests or component lifecycles can prevent the application from crashing due to unexpected data or states.

    b) Hydration Mismatch Detection and Resolution:

    • While not explicitly covered in the sources, Next.js offers tools and techniques to detect and resolve hydration mismatches:
    • react-hydration-error-boundary: This library can help capture and handle hydration errors, providing insights into their causes and enabling graceful recovery.
    • Data Fetching Strategies: Carefully choosing and implementing data fetching strategies (e.g., getServerSideProps, getStaticProps) can ensure that the data used for rendering is consistent between the server and client.
    • Unit and Integration Testing: Writing tests to verify that components render consistently on both the server and client can help identify and prevent hydration issues early in the development process.

    4. Additional Considerations (Not from Sources)

    Third-Party Libraries: Be mindful of how third-party libraries handle SSR. Some libraries might not be SSR-compatible or might require specific configuration to work correctly in a Next.js environment. Always consult the library’s documentation for guidance.

    State Management: If your application uses complex state management, ensure that your state is initialized and synchronized correctly on both the server and client. Mismatches in initial state can easily lead to hydration errors.

    In Summary

    Preventing SSR and hydration errors requires a combination of careful planning, coding practices, and leveraging Next.js’s features and tools. While the sources provide valuable examples, they could be further strengthened with more comprehensive error handling and explicit hydration mismatch detection strategies.

    Here’s a bibliography for building a SaaS AI platform using Next.js 13, React, Tailwind CSS, Prisma, and Stripe:

    Books

    1. Holt, J. (2022). Building Scalable SaaS Applications with Next.js: A Guide to High-Performance, Modular Web Applications. Packt Publishing.
    • This book covers advanced topics on creating SaaS applications with a focus on performance optimization, modular architecture, and deploying with Next.js.
    1. Grider, S. (2023). Mastering React and TypeScript: Build Modern Full-Stack Applications. Independently published.
    • A detailed guide on combining React and TypeScript to build reliable, modern front-end applications, especially useful for Next.js users looking to build scalable SaaS products.
    1. Bell, A. (2023). Full Stack with Prisma: Database-Driven Web Applications for Developers. O’Reilly Media.
    • An in-depth resource on using Prisma ORM to handle data in full-stack applications, covering setup, database relationships, and optimization.
    1. Carlson, T. (2022). Mastering Tailwind CSS: Styling Modern Web Applications with Ease. Manning Publications.
    • A focused guide on using Tailwind CSS for design systems in modern web applications, ideal for creating clean, responsive UIs in SaaS platforms.

    Articles and Blog Posts

    1. Next.js Blog (2023). “What’s New in Next.js 13: Turbocharged Performance and API Routes.” Retrieved from https://nextjs.org/blog
    • Official Next.js blog explaining the latest features in Next.js 13 that are particularly useful for SaaS development, including server components, routing, and performance improvements.
    1. Stripe Docs. (2023). “Setting Up Stripe for SaaS Billing.” Retrieved from https://stripe.com/docs
    • Stripe documentation with sections specifically addressing SaaS billing, including customer management, subscriptions, and usage-based billing.
    1. Lee Robinson. (2023). “Creating a SaaS with Next.js, Prisma, and Stripe.” Vercel Blog. Retrieved from https://vercel.com/blog
    • A comprehensive guide on integrating Prisma and Stripe with Next.js, featuring a sample application and practical tips for SaaS billing.
    1. Dev.to (2023). “How to Integrate Prisma and Next.js for Data-Driven Apps.” Retrieved from https://dev.to
    • Step-by-step tutorial on setting up Prisma with Next.js for database management, with an emphasis on SaaS product scenarios.

    Documentation

    1. Next.js Documentation (2023). Next.js 13 Documentation. Retrieved from https://nextjs.org/docs
    • Official Next.js documentation for the latest version, which includes information on server components, API routes, and deployment tips for SaaS applications.
    1. Tailwind CSS Documentation (2023). Tailwind CSS Documentation. Retrieved from https://tailwindcss.com/docs
    • The Tailwind CSS official docs provide everything you need to build responsive UIs, including customizations and component-based styling best practices for SaaS applications.
    1. Prisma Documentation (2023). Prisma Documentation. Retrieved from https://www.prisma.io/docs
    • Comprehensive resource on Prisma, including ORM setup, schema modeling, and advanced query functions tailored for full-stack SaaS applications.
    1. Stripe API Documentation (2023). Stripe API Documentation. Retrieved from https://stripe.com/docs/api
    • Essential documentation for implementing Stripe API features for payments, subscriptions, and webhook integrations in SaaS platforms.

    Video Courses

    1. Udemy. (2023). “Build and Scale a SaaS Product with Next.js, Prisma & Stripe.” Retrieved from https://www.udemy.com
    • Covers the end-to-end process of building and scaling a SaaS product, with a focus on integrating Stripe for billing and Prisma for data management.
    1. Frontend Masters. (2023). “Advanced Next.js 13 and SaaS Application Development.” Retrieved from https://frontendmasters.com
    • Focuses on the new features in Next.js 13, along with practical lessons on using Tailwind, React, and Prisma for developing SaaS platforms.
    1. YouTube – Fireship. (2023). “Next.js 13 Crash Course – Build a Full-Stack SaaS.” Retrieved from https://youtube.com/fireship
    • A quick but in-depth look at the essentials for building a full-stack SaaS with Next.js 13, covering Prisma, Tailwind, and Stripe integration.

    These resources offer a solid foundation for building a SaaS AI platform, covering front-end and back-end development, payment processing, and styling. Let me know if you’d like more specific tutorials or if you have questions about a particular topic!

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog