You are on page 1of 28

Creating a Restaurant Website

Building the header of your restaurant app


ReactMeals
Video 1

002 Starting Setup

003 Adding a Header Component


Header.js

import { Fragment } from "react";


import mealsImage from '../../assets/meals.jpg';
import classes from './Header.module.css';

const Header = () =>{


return(
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<button>Cart</button>
</header>
<div className={classes['main-image']}>
<img src={mealsImage} alt="Atable full of delicious food "/>
</div>
</Fragment>
);
}
export default Header;

app.js

import Header from "./componenets/Layout/Header";


import { Fragment } from "react";

function App() {
return (
<Fragment>
<h2>Let's get started!</h2>
<Header></Header>
</Fragment>

);
}

export default App;


004 Adding the Cart Button Component

HeaderCardButton.js
import CartIcon from "../Cart/CartIcon";
import classes from './HeaderCartButton.module.css'

const HeaderCardButton = (props) =>


{
return (
<button className={classes.button}>
<span className={classes.icon}>
<CartIcon/>
</span>
<span>
Your Cart
</span>
<span className={classes.badge}>3</span>
</button>
);
};
export default HeaderCardButton;
Header.js
import { Fragment } from "react";
import mealsImage from '../../assets/meals.jpg';
import classes from './Header.module.css';
import HeaderCardButton from "./HeaderCardButton";

const Header = () =>{


return(
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<HeaderCardButton/>
</header>
<div className={classes['main-image']}>
<img src={mealsImage} alt="Atable full of delicious food "/>
</div>
</Fragment>
);
}
export default Header;
svg

const CartIcon = () => {


return (
<svg
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 20 20'
fill='currentColor'
>
<path d='M3 1a1 1 0 000 2h1.22l.305 1.222a.997.997 0 00.01.042l1.358
5.43-.893.892C3.74 11.846 4.632 14 6.414 14H15a1 1 0 000-2H6.414l1-1H14a1 1 0
00.894-.553l3-6A1 1 0 0017 3H6.28l-.31-1.243A1 1 0 005 1H3zM16 16.5a1.5 1.5 0 11-
3 0 1.5 1.5 0 013 0zM6.5 18a1.5 1.5 0 100-3 1.5 1.5 0 000 3z' />
</svg>
);
};

export default CartIcon;


Task details
Download the resource from this link.
Watch videos 1 and 2 from the following link and understand how to maintain the file structure.
Deliverable [TRY DOING THIS BY YOURSELF]

1. Try building the header like this https://drive.google.com/file/d/1i5hLhqdtPLFsrw20m4MJl3GQpdZyyq_q/


view?usp=sharing .Its fine if it doesn't look exactly like the image .
2. The cart button can for the time being show 0 cart items. You don't have to write the logic for counting
elements in the cart. We can do that later

Its important that you try doing this by yourself. Its ok if you don't follow the best design patterns
and file structure.
If stuck for very long watch video 3 and 4 from the above link.
Once done, push the code to git and upload the commit id

Add Restaurant Summary


Video 5
AvailableMeals.js

import classes from './AvailableMeals.module.css';

const DUMMY_MEALS = [
{
id: 'm1',
name: 'Sushi',
description: 'Finest fish and veggies',
price: 22.99,
},
{
id: 'm2',
name: 'Schnitzel',
description: 'A german specialty!',
price: 16.5,
},
{
id: 'm3',
name: 'Barbecue Burger',
description: 'American, raw, meaty',
price: 12.99,
},
{
id: 'm4',
name: 'Green Bowl',
description: 'Healthy...and green...',
price: 18.99,
},
];

const AvailableMeals = ()=>


{
const mealsList = DUMMY_MEALS.map(meal =>
<li>{meal.name}</li>
);

return (
// <section className={classes.mealsList}>
<section className={classes.meals}>
<ul>
{mealsList}
</ul>
</section>
);
}
export default AvailableMeals;

Making the Items visible


Deliverable
You have to show the meals like this https://drive.google.com/file/d/1Rg-
f8dFzRZgARdnaNxuqVe5HyGeqnsCj/view?usp=sharing.
Take an an array of dummy meal Items and show it on the screen.
The style do not have to exactly match.
Try doing this by yourself.

If stuck forever watch video 6 from the following link.

Once the code is complete, push the code to git and upload commit ID.
MealItem.js

import classes from './MealItem.module.css'


const MealItem = props =>
{
const price = `$${props.price.toFixed(2)}`;
return (
<li className={classes.meal}>
<div>
<h3>{props.name}</h3>
<div className={classes.description}>{props.description}</div>
<div className={classes.price}>{price}</div>
</div>
<div>

</div>
</li>
);
}
export default MealItem;
https://github.com/pandey0801/Making-the-Items-visible

Adding a Form
Task details
Deliverable [TRY DOING THIS BY YOURSELF]

1. You have to add a form for user to select number of quantity of item he want to order.
2. Also add an "ADD Button"
3. On clicking on the add button nothing should happen now. We will add logic later on

Finally the screen should look like this


https://drive.google.com/file/d/1yhNQqiIQGcrGohOvLCUDvxGLVjfsXnvd/view?usp=sharing.

If stuck for very long watch video 7 from the following link.

Push the code to git and upload the commit ID


Input.js
import classes from './Input.module.css'
const Input = props=>
{
return <div className={classes.input}>
<label htmlFor={props.input.id}>{props.label}</label>
<input {...props.input} />
</div>
}
export default Input;

MealItemForm.js
import classes from './MealItemForm.module.css'
import Input from '../UI/Input';
const MealItemForm = props =>
{
return <from className={classes.form}>
{/* <input / */}
<Input label ="Amount" input={{
id: 'amount',
type: 'number',
min: "1",
max: '5',
step: '1',
defaultValue: '1'
}} />
<button>+ ADD</button>

</from>
};

export default MealItemForm

https://github.com/pandey0801/Adding-a-Form

Making a hard Coded Cart without any Functionality

Deliverable
1. You had learnt about React.createportal() previously . Use that to build this
https://drive.google.com/file/d/1_3zEu9cRIno287crU7CS-QSGWk1AfNLQ/view?usp=sharing. It is pretty
simple i feel.
2. Hard code the contents of the cart.
3. When the user comes to the page the page should directly open .
4. You don't have to make the close and order button work.
5. We will do the functionality portion in the next task

If stuck for long watch video 9 and 10 from the following link .

Push the code to git and upload the commit Id

Card.js

import classes from './Cart.module.css'


import Modal from '../UI/Modal';

const Cart = props =>


{
const cartItem = <ul className={classes['cart-items']}>
{[{id: 'c1',
name:'Sushi',
amount:2,
price:12.99}
].map((item) => <li>{item.name}</li>)}</ul>;
return (
<Modal>
<div>
{cartItem}
<div className={classes.total}>
<span>Total Amount</span>
<span>35.63</span>
</div>
<div className={classes.actions}>
<button className={classes['button--alt']}>Close</button>
<button className={classes.button}>Order</button>
</div>
</div>
</Modal>
);
}

export default Cart;


Modal.js

import { Fragment } from 'react';


import ReactDOM from 'react-dom';

import classes from './Modal.module.css';

const Backdrop = (props) => {


return <div className={classes.backdrop} onClick={props.onClose}/>;
};

const ModalOverlay = (props) => {


return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
);
};

const portalElement = document.getElementById('overlays');

const Modal = (props) => {

return (
<Fragment>
{ReactDOM.createPortal(<Backdrop onClose={props.onClose} />,
portalElement)}
{ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement
)}
</Fragment>
);
};

export default Modal;

https://github.com/pandey0801/Making-a-hard-Coded-Cart-without-any-Functionality
Cart open and close
Task details
Deliverable

1. When the user clicks on the cart icon , the cart should open up
https://drive.google.com/file/d/13TchLhjm_Ubj5Co5bKXVzLQXUaTqyfaW/view?usp=sharing. [TRY IT BY
YOPURSELF]
2. This could be simply done by using hooks, try it by yourself.
3. Now when the user clicks on the close button , the cart should close. Watch video 11 from the
following link to understand how to do it.

Push the code to git and upload the commit ID


https://github.com/pandey0801/Cart-open-and-close-

app.js
import Header from "./componenets/Layout/Header";
import { Fragment , useState } from "react";
import Meals from "./componenets/Meals/Meals";
import Cart from "./componenets/Cart/Cart";

function App() {
// console.log("sdds");
const [cartIsShow, setCartIsShow] = useState(false);

const showCartHandler = () =>


{
setCartIsShow(true);
}

const hideCartHandler = () =>


{
setCartIsShow(false);
}

return (
<Fragment>
{cartIsShow && <Cart onCloseCart={hideCartHandler}/>}
<Header onShowCart={showCartHandler}/>
<Meals />
</Fragment>

);
}

export default App;

header.js
import { Fragment } from "react";
import mealsImage from '../../assets/meals.jpg';
import classes from './Header.module.css';
import HeaderCardButton from "./HeaderCardButton";

const Header = (props) =>{


return(
<Fragment>
<header className={classes.header}>
<h1>ReactMeals</h1>
<HeaderCardButton onClickkk={props.onShowCart}/>
</header>
<div className={classes['main-image']}>
<img src={mealsImage} alt="A table full of delicious food "/>
</div>
</Fragment>
);
}
export default Header;
HeaderCartButton.js
import CartIcon from "../Cart/CartIcon";
import classes from './HeaderCartButton.module.css'
const HeaderCardButton = (props) =>
{
return (
<button className={classes.button} onClick={props.onClickkk}>
<span className={classes.icon}>
<CartIcon/>
</span>
<span>
Your Cart
</span>
<span className={classes.badge}>3</span>
</button>
);
};
export default HeaderCardButton;

cart.js
import classes from './Cart.module.css'
import Modal from '../UI/Modal';

const Cart = props =>


{
const cartItem = <ul className={classes['cart-items']}>
{[{id: 'c1',
name:'Sushi',
amount:2,
price:12.99}
].map((item) => <li>{item.name}</li>)}</ul>;
return (
<Modal onClose={props.onCloseCart}>
<div>
{cartItem}
<div className={classes.total}>
<span>Total Amount</span>
<span>35.63</span>
</div>
<div className={classes.actions}>
<button className={classes['button--alt']}
onClick={props.onCloseCart}>Close</button>
<button className={classes.button}>Order</button>
</div>
</div>
</Modal>
);
}

export default Cart;

modal.js
import { Fragment } from 'react';
import ReactDOM from 'react-dom';

import classes from './Modal.module.css';

const Backdrop = (props) => {


// console.log(props);
return <div className={classes.backdrop} onClick={props.onClose} />;
};

const ModalOverlay = (props) => {


return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
);
};

const portalElement = document.getElementById('overlays');

const Modal = (props) => {

return (
<Fragment>
{ReactDOM.createPortal(<Backdrop onClose={props.onClose} />,
portalElement)}
{ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement
)}
</Fragment>
);
};

export default Modal;


DIY- Implementing the cart Itemns page

CartContext.js
import React from 'react';

const CartContext = React.createContext({


items: [],
totalAmount: 0,
addItem: (item) => {},
removeItem: (id) => {}
});

export default CartContext;

CartProvider.js

import { useReducer } from 'react';


import CartContext from './Cart-Context';

const defaultCartState = {
items: [],
totalAmount: 0,
};

const cartReducer = (state, action) => {


if (action.type === 'ADD') {
const updatedTotalAmount =
state.totalAmount + action.item.price * action.item.amount;

const existingCartItemIndex = state.items.findIndex(


(item) => item.id === action.item.id
);
const existingCartItem = state.items[existingCartItemIndex];
let updatedItems;

if (existingCartItem) {
const updatedItem = {
...existingCartItem,
amount: existingCartItem.amount + action.item.amount,
};
updatedItems = [...state.items];
updatedItems[existingCartItemIndex] = updatedItem;
} else {
updatedItems = state.items.concat(action.item);
}

return {
items: updatedItems,
totalAmount: updatedTotalAmount,
};
}
if (action.type === 'REMOVE') {
const existingCartItemIndex = state.items.findIndex(
(item) => item.id === action.id
);
const existingItem = state.items[existingCartItemIndex];
const updatedTotalAmount = state.totalAmount - existingItem.price;
let updatedItems;
if (existingItem.amount === 1) {
updatedItems = state.items.filter(item => item.id !== action.id);
} else {
const updatedItem = { ...existingItem, amount: existingItem.amount - 1 };
updatedItems = [...state.items];
updatedItems[existingCartItemIndex] = updatedItem;
}

return {
items: updatedItems,
totalAmount: updatedTotalAmount
};
}
return defaultCartState;
};

const CartProvider = (props) => {


const [cartState, dispatchCartAction] = useReducer(
cartReducer,
defaultCartState
);

const addItemToCartHandler = (item) => {


dispatchCartAction({ type: 'ADD', item: item });
};

const removeItemFromCartHandler = (id) => {


dispatchCartAction({ type: 'REMOVE', id: id });
};

const cartContext = {
items: cartState.items,
totalAmount: cartState.totalAmount,
addItem: addItemToCartHandler,
removeItem: removeItemFromCartHandler,
};

return (
<CartContext.Provider value={cartContext}>
{props.children}
</CartContext.Provider>
);
};

export default CartProvider;


app.js

import Header from "./componenets/Layout/Header";


import { Fragment , useState } from "react";
import Meals from "./componenets/Meals/Meals";
import Cart from "./componenets/Cart/Cart";
import CartProvider from "./Store/CartProvider";

function App() {
// console.log("sdds");
const [cartIsShow, setCartIsShow] = useState(false);
const showCartHandler = () =>
{
setCartIsShow(true);
}

const hideCartHandler = () =>


{
setCartIsShow(false);
}

return (
<CartProvider>
{cartIsShow && <Cart onCloseCart={hideCartHandler}/>}
<Header onShowCart={showCartHandler}/>
<Meals />
</CartProvider>

);
}

export default App;

https://github.com/pandey0801/DIY--Implementing-the-cart-Itemns-page
Test

import { useReducer } from 'react';


import CartContext from './Cart-Context';

const defaultCartState = {
items: [],
totalAmount: 0,
};

const cartReducer = (state, action) => {


if (action.type === 'ADD') {
const updatedTotalAmount =
state.totalAmount + action.item.price * action.item.amount;

const existingCartItemIndex = state.items.findIndex(


(item) => item.id === action.item.id

);
const existingCartItem = state.items[existingCartItemIndex];
let updatedItems;

if (existingCartItem) {
const updatedItem = {
...existingCartItem,
amount: existingCartItem.amount + action.item.amount,
};
updatedItems = [...state.items];
updatedItems[existingCartItemIndex] = updatedItem;
} else {
updatedItems = state.items.concat(action.item);
}

return {
items: updatedItems,
totalAmount: updatedTotalAmount,
};
}
if (action.type === 'REMOVE') {
const existingCartItemIndex = state.items.findIndex(
(item) => item.id === action.id
);
const existingItem = state.items[existingCartItemIndex];
const updatedTotalAmount = state.totalAmount - existingItem.price;
let updatedItems;
if (existingItem.amount === 1) {
updatedItems = state.items.filter(item => item.id !== action.id);
} else {
const updatedItem = { ...existingItem, amount: existingItem.amount - 1 };
updatedItems = [...state.items];
updatedItems[existingCartItemIndex] = updatedItem;
}

return {
items: updatedItems,
totalAmount: updatedTotalAmount
};
}

return defaultCartState;
};

const CartProvider = (props) => {


const [cartState, dispatchCartAction] = useReducer(
cartReducer,
defaultCartState
);

const addItemToCartHandler = (item) => {


dispatchCartAction({ type: 'ADD', item: item });
};

const removeItemFromCartHandler = (id) => {


dispatchCartAction({ type: 'REMOVE', id: id });
};

const cartContext = {
items: cartState.items,
totalAmount: cartState.totalAmount,

addItem: addItemToCartHandler,
removeItem: removeItemFromCartHandler,
};

console.log(cartContext)

return (
<CartContext.Provider value={cartContext}>
{props.children}
</CartContext.Provider>
);
};

export default CartProvider;


11/4/2024

MOST IMPORTANT FOR INTERVIEW QUESTIONS


Watch video 1 and 2 from the following link and answer the following

1. What are the 4 things that the component cares about. Explain each one of them.
2. What is Virtual DOM.
3. How does Virtual DOM diffing make React fast

1.the 4 things that the component cares about.


Props (Properties): Props are inputs that a component receives from its parent component.
They are immutable and provide a way to pass data from one component to another. Props
allow components to be reusable and configurable based on the data they receive.

State: State represents the internal data of a component that can change over time. Unlike
props, state is mutable and managed within the component itself. Components can initialize
state, update it based on user interactions or other events, and trigger re-renders to reflect the
updated state.

Context: Context provides a way to share data across the component tree without manually
passing props down through each level of nesting. It allows components to subscribe to a
context and access the data it provides. Context is useful for providing global data, such as
themes, user authentication, or language preferences, to multiple components in an
application.
Virtual DOM (Document Object Model): The Virtual DOM is a lightweight representation of
the actual DOM in memory. React uses the Virtual DOM to optimize rendering performance
by comparing changes in the Virtual DOM and selectively updating the actual DOM only
where necessary. This approach minimizes browser reflows and repaints, leading to faster
rendering and better user experience.

2.Virtual DOM Tree Creation: When a React component renders, it creates a corresponding
Virtual DOM tree, which mirrors the structure of the actual DOM but is constructed using
plain JavaScript objects.

Efficient Updates: When changes are made to a component's state or props, React doesn't
immediately update the actual DOM. Instead, it first updates the Virtual DOM tree with the
new state or props.

Reconciliation: React then compares the updated Virtual DOM tree with the previous one
using a process called reconciliation. It identifies the differences (or "diffs") between the two
trees efficiently, thanks to its diffing algorithm.

Minimal DOM Updates: After identifying the differences, React determines the minimal set
of changes needed to update the actual DOM. It only applies these changes to the real DOM,
avoiding unnecessary re-renders and updates.

3.Virtual DOM is a lightweight copy of the actual DOM, used by React to efficiently update
the user interface. When changes occur, React compares the current Virtual DOM with the
previous one, identifying the minimal set of updates needed to reflect the changes. This
process, known as "diffing,"

Watch video 3 from above link

1.."It all comes down to state change." What does the trainer mean by this.
2..Why does "APP RUNNING" get printed whenever we click on Toggle Paragragh button

1..when we change a state it will change the virtual DOM then Virtual DOM change the actual DOM
2..because it re rending the component

Watch video 4 from above link

1Why does only the <p> tag flash?Please Explain.


2When we pass show = false [HARDCODED VALUE], why does DemoOutput get reevaluated ?
3Does the <p> tag flash? Explain why?

1.the <p> tag flash because the <p> added in the actual DOM
2.because when every the parent component render the child should also render that why we getting
DemoOutput get reevaluated
3.no the <p> not tag flash. because the hardcoded value and actual DOM is not changing

MOST IMPORTANT COCEPT FOR INTERVIEW TASK AND INTERVIEW.


1. Watch video 5 from the following link and answer the following
2. Why do we use React Memo? What are the advantages of React Memo?
3. When should we not use React Memo?
4. Why do we use React Memo on Demooutput component and not on Myparagraph component
inside it?
5. on applying React memo to button component , why does it get reevaluated whenever we click
on "Toggle Paragraph" button.

1.React.memo is a higher-order component provided by React that is used for


optimizing functional components by preventing unnecessary re-renders. It
works for functional components. React.memo caches the result of a component's
rendering, and if the component receives the same props, it returns the cached
result without re-rendering. This optimization can lead to improved performance by
avoiding unnecessary re-renders, especially in scenarios where components receive
the same props frequently.

2.If your component gets lots of different props often or has complicated rendering
logic, it's best not to use React.memo. This means if the component's appearance
changes frequently or if it has many nested parts, memoization might not help much
and could even slow things down.

3.Demooutput component getting the props (false) value which not changing.
Myparagraph is always calling and changing value

4. it get reevaluated whenever we click on "Toggle Paragraph" button. because it


getting different reference value in each time. so that button component every time

Watch video 6 from above link and answer the following

1.How does useCallback solve the above problem of preventing reevaluation whenever we click on
"Toggle Paragraph" button.Please explain the logic.
2.What is the second argument of usecallback? What does it do?

1.In React, useCallback is a hook used to store a function and memoize it, meaning it
remembers the function instance between renders. This helps optimize performance
by preventing unnecessary re-creations of the function on every render, especially
when passing functions as dependencies to other hooks or components. By
specifying dependencies, useCallback ensures that the function is only recreated
when those dependencies change, reducing unnecessary re-renders and improving
the efficiency of your React application. const memoizedCallback = useCallback(
() => {
// Function body
},
[/* Dependency array */]
);
2.The second argument of useCallback is an array of dependencies. This argument
specifies the values that the callback function depends on. If any of these
dependencies change, useCallback will re-create the function. If the dependencies
remain the same between renders, useCallback will return the same memoized
function instance, optimizing performance by avoiding unnecessary re-renders.

Watch video 7

1.Why do we have to put allowToggle in the dependency list of usecallback?


2.Why does the entire component not work without putting allowToggle in the dependency list of
usecallback?

1.allowToggle is a sate change that changes over time and is used inside the
callback function, then it should be included in the dependency list of useCallback.
This ensures that the callback is recreated whenever allowToggle changes,
guaranteeing that the latest value of allowToggle is captured inside the callback.
2.If allowToggle is not included in the dependency list of useCallback, the callback
function will not be recreated when allowToggle changes. This means that the
callback will continue to reference the initial value of allowToggle, leading to
incorrect behavior when allowToggle is updated. As a result, the component may not
work as expected because it relies on the updated value of allowToggle to determine
its behavior.

You might also like