Monday, October 31, 2022

React Adding styles function

   const btnClasses=`${classes.button} ${classes.bump}`;//adding styles

  return (
    <Fragment>
      <button className={btnClasses} onClick={props.onClick}>
     //initially <button className={classes.button} onClick={props.onClick}>




Sunday, October 30, 2022

React Context: use context instead of passing data with usestate to nested components

Readme


1. create Cart-Context.js with default structure (ie, **{items:[],totalAmount:0,addItem:(item)=>{},removeItem:(id)=>{}}**)

2. create CartProvider.js with above Cart-Context default obj structure,using it with dynamic values 

{ items:[],totalAmount:0, addItem:addItemToCartHandler,removeItem:removeItemFromCartHandler },

ii.Create reducer and dispatch data from functions with addItemToCartHandler, removeItemFromCartHandler

iii.create usestate and add reducer to usestate

iv.<CartContext.Provider value={cartContext}> {props.children} </CartContext.Provider>

3.In app.js <CartProvider>  <Header onShowCart={showCartHandler}/>... </CartProvider>

4.In header.js <header className={classes.header}><HeaderCartButton onClick={props.onShowCart}></HeaderCartButton></header>

5.HeaderCartButton.js :


const HeaderCartButton = (props) => {

    const cartCtx= useContext(CartContext);

    const numberOfCartItems= cartCtx.items.reduce((curNumber, item)=>{

        return curNumber+item.amount;

    },0);

  return (

    <Fragment>

      <button className={classes.button} onClick={props.onClick}>

        {/* 3. for popopening */}

        <span className={classes.icon}>

          <CartIcon/>

        </span>

        <span>Cart</span>

        <span className={classes.badge}>{numberOfCartItems}</span>

      </button>

    </Fragment>

  );

};

_________________________________________________________


Cart-Context.js

import React from "react";

const CartContext=React.createContext({
    items:[],
    totalAmount:0,
    addItem:(item)=>{},
    removeItem:(id)=>{}
});

export default CartContext


2.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 updatedItems= state.items.concat(action.item);
    const updatedTotalAmount=state.totalAmount+action.item.price*action.item.amount;
    return {
        items:updatedItems,
        totalAmount:updatedTotalAmount
    };
    }else if(action.type="REMOVE"){

    }
   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={ // first add these below lines next write reducer code.
        // items:[],totalAmount:0, initially like this b4 adding reducer
        items:cartstate.items,
        totalAmount:cartstate.totalAmount,
        addItem:addItemToCartHandler,
        removeItem:removeItemFromCartHandler
    };
    return <CartContext.Provider value={cartContext}>
       {props.children}
    </CartContext.Provider>
}

export default CartProvider;

3.App.js

 return (
    <CartProvider>
      {cartIsShown && <Cart onClose={hideCartHandler}/>}
      <Header onShowCart={showCartHandler}/>
       {/* 1. for popopening */}
      <main>
        <Meals />
      </main>
    </CartProvider>
  );
}

export default App;
4.Header.js 

import React, { Fragment } from "react";
import HeaderCartButton from "./HeaderCartButton";
import classes from './Header.module.css';
import mealsImage from '../../assets/meals.jpg'
const Header = (props)=>{
    return <Fragment>
        <header className={classes.header}>
        <h1>ReactMeals</h1>
        <HeaderCartButton onClick={props.onShowCart}></HeaderCartButton>
         {/* 2. for popopening */}
        </header>
        <div className={classes['main-image']}><img src={mealsImage}></img></div>
    </Fragment>
}
export default Header;

HeaderCartButton.js
import CartContext from "../../store/cart-context";


const HeaderCartButton = (props) => {
    const cartCtx= useContext(CartContext);
    const numberOfCartItems= cartCtx.items.reduce((curNumber, item)=>{
        return curNumber+item.amount;
    },0);
  return (
    <Fragment>
      <button className={classes.button} onClick={props.onClick}>
        {/* 3. for popopening */}
        <span className={classes.icon}>
          <CartIcon/>
        </span>
        <span>Cart</span>
        <span className={classes.badge}>{numberOfCartItems}</span>
      </button>
    </Fragment>
  );
};
export default HeaderCartButton;

Saturday, October 22, 2022

React: passing data from multiple child to parent -

     In 1.app.js 1 <Header onShowCart={showCartHandler}/> Go to 2.Header Component 2 <HeaderCartButton onClick={props.onShowCart}></HeaderCartButton> Go to 3.HeaderCardButton Component 3 <button className={classes.button} onClick={props.onClick}>

App.js

Header.js
HeaderCartButton.js


Tuesday, October 18, 2022

React Input.js COmponent --CART proj

 input.js

import React, { Fragment } from "react";
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

 {/* {label props.input.id} added as {...props.input}for inp,wit  spread oper auto added type=txt  */}
       
input.module.css
.input {
    display: flex;
    align-items: center;
    margin-bottom: 0.5rem;
  }
 
  .input label {
    font-weight: bold;
    margin-right: 1rem;
  }
 
  .input input {
    width: 3rem;
    border-radius: 5px;
    border: 1px solid #ccc;
    font: inherit;
    padding-left: 0.5rem;
  }

MealItemForm:
 <Input
          label="Amount"
          input={{
            id: "amount_"+props.id,
            type: "number",
            min: "1",
            max: "5",
            step: "1",
            defaultValue: "1",
          }}
        />
        {/* with one {} evaluate js exp, with 2 {{}} sets as obj */}




React: passing data/keys to childs


1.Available Meals:(Result data)

const AvailableMeals = () => {
  const mealsList = DUMMY_MEALS.map((meal) => <MealItem key={meal.id} name={meal.name} description={meal.description} price={meal.price}/>);
2.MealItem: (Row Data)
 <div> <MealItemForm id={props.id}></MealItemForm></div>


3.MealItemForm

const MealItemForm = (props) => {
  return (
    <Fragment>
      <form className={classes.form}>
        <Input
          label="Amount"
          input={{
            id: "amount_"+props.id,
            type: "number",
            min: "1",
            max: "5",
            step: "1",
            defaultValue: "1",
          }}
        />
        {/* with one {} evaluate js exp, with 2 {{}} sets as obj */}
        <button>+ Add</button>
      </form>
    </Fragment>
  );
};

 

Monday, October 17, 2022

React: Card.js

 Card.js

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

const Card = props => {
  return <div className={classes.card}>{props.children}</div>
};

export default Card; Card.css
.card {
    padding: 1rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
    border-radius: 14px;
    background-color: white;
  }

Saturday, October 15, 2022

React: Filling user input box misses highlights that input on submit. (order top to bottom)

 129 lec

diving into forward refs

React: creating component for input- for reusable input box

 Login.js

Initially 

<div
          className={`${classes.control} ${
            emailstate.isValid === false ? classes.invalid : ''
          }`}
        >
          <label htmlFor="email">E-Mail</label>
          <input
            type="email"
            id="email"
            value={emailstate.value}
            onChange={emailChangeHandler}
            onBlur={validateEmailHandler}
          />
        </div>



Input.js
import React from "react";
import classes from './Input/Input.module.css'
const Input=(props)=>{
    return <div
    className={`${classes.control} ${
      props.isValid === false ? classes.invalid : ''
    }`}
  >
    <label htmlFor="{props.id}">{props.label}</label>
    <input
      type="{props.type}"
      id="{props.id}"
      value={props.value}
      onChange={props.onChange}
      onBlur={props.onBlur}
    />
  </div>
}

export default Input;

Login.js changed to
 <Input
          id="email"
          label="E-mail"
          type="email"
          isValid={emailIsValid}
          value={emailstate.value}
          onChange={emailChangeHandler}
          onBlur={validateEmailHandler}
        />














Friday, October 14, 2022

React :logout separate component using createcontext

auth-context.js

import React, { useState,useEffect } from "react";
const AuthContext = React.createContext({
  isLoggedIn: false,
  onLogout: () => {}, //for better ide autocompletion test in navigation <button onclick=ctx.onlogout autoretrived
  onLogin:(email,password)=>{}
});

export const AuthContextProvider = (props) => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  useEffect(()=>{
    const storedLocalStorage=localStorage.getItem('isLoggedIn');
    if(storedLocalStorage==="1"){
      setIsLoggedIn(true);
    }
  },[]);
  const logoutHandler = () => {
    localStorage.removeItem('isLoggedIn');
    setIsLoggedIn(false);
  };
  const loginHandler = () => {
    localStorage.setItem('isLoggedIn','1');
    setIsLoggedIn(true);
  };
  return (
    <AuthContext.Provider
      value={{ isLoggedIn: isLoggedIn, onLogout: logoutHandler,onLogin:loginHandler }}
    >
      {props.children}
    </AuthContext.Provider>
  );
};
// exporting both files here AuthContextProvider and AUthcontext

export default AuthContext;

Navigation:
import React, {useContext} from 'react';
import AuthContext from '../../store/auth-context';

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

const Navigation = () => {
 const ctx=  useContext(AuthContext);  //changes: newly added this and imported useContext
  return (
    // <AuthContext.Consumer>   //Removed these 3 lines
    //   {(ctx)=>{
    //     return (
        <nav className={classes.nav}>
          <ul>
            {ctx.isLoggedIn && (
              <li>
                <a href="/">Users</a>
              </li>
            )}
            {/* {props.isLoggedIn && ( */}
            {ctx.isLoggedIn && (
              <li>
                <a href="/">Admin</a>
              </li>
            )}
            {ctx.isLoggedIn && (
              <li>
                <button onClick={ctx.onLogout}>Logout</button>
              </li>
            )}
          </ul>
        </nav>
    //     )
    //   }}  
    //   {/* will get data of auth context comp */}
   
    // </AuthContext.Consumer>
  );
};

export default Navigation;


APp.js
import React, { useContext } from 'react';

import Login from './components/Login/Login';
import Home from './components/Home/Home';
import MainHeader from './components/MainHeader/MainHeader';
 import AuthContext from './store/auth-context';

function App() {
 const ctx= useContext(AuthContext);   // added new
  //all moved to auth-context.js
//   const [isLoggedIn, setIsLoggedIn] = useState(false);

// useEffect(()=>{
//   const storedLocalStorage=localStorage.getItem('isLoggedIn');
//   if(storedLocalStorage==="1"){
//     setIsLoggedIn(true);
//   }
// },[]);
//   const loginHandler = (email, password) => {
//     // We should of course check email and password
//     // But it's just a dummy/ demo anyways
//     localStorage.removeItem('isLoggedIn');
//     localStorage.setItem('isLoggedIn','1');
//     setIsLoggedIn(true);
//   };
 
//   const logoutHandler = () => {
//     localStorage.setItem('isLoggedIn','0');
//     setIsLoggedIn(false);
//   };

  return (
    <React.Fragment>
      {/* // <AuthContext.Provider value={{isLoggedIn:isLoggedIn,onLogout:logoutHandler}}> */}
      <MainHeader/>
      <main>
        {!ctx.isLoggedIn && <Login/>}
        {ctx.isLoggedIn && <Home/>}
      </main>
      {/* // </AuthContext.Provider> */}
      </React.Fragment>
  );
}

export default App;

index.js
root.render(<AuthContextProvider><App /></AuthContextProvider>);











Thursday, October 13, 2022

React: usecontext for islogin, islogout (showing tabs if user login)

 -----------------------------------------------auth-context.js--------------------------------------------------

import React from "react";

const AuthContext= React.createContext({

    isLoggedIn:false

})

export default AuthContext;


-----------------------------------------------app.js-----------------------------------------------------------

HERE NEED TO ADD AS PROVIDER ie.,AuthContext.Provider


  <AuthContext.Provider value={{isLoggedIn:isLoggedIn}}>

      <MainHeader onLogout={logoutHandler} />

      {/*1 <MainHeader isAuthenticated={isLoggedIn} onLogout={logoutHandler} /> */}

      <main>

        {!isLoggedIn && <Login onLogin={loginHandler} />}

        {isLoggedIn && <Home onLogout={logoutHandler} />}

      </main>

      </AuthContext.Provider>


----------------------------------------------Navigation.js-----------------------------------------------------

1. with use context hook.............

const Navigation = (props) => {

 const ctx=  useContext(AuthContext);  //changes: newly added this and imported useContext

  return (

    // <AuthContext.Consumer>   //Removed these 3 lines

    //   {(ctx)=>{

    //     return (

        <nav className={classes.nav}>

          <ul>

            {ctx.isLoggedIn && (

              <li>

                <a href="/">Users</a>

              </li>

            )}

            {/* {props.isLoggedIn && ( */}

            {ctx.isLoggedIn && (

              <li>

                <a href="/">Admin</a>

              </li>

            )}

            {ctx.isLoggedIn && (

              <li>

                <button onClick={props.onLogout}>Logout</button>

              </li>

            )}

          </ul>

        </nav>

    //     )

    //   }}  

    //   {/* will get data of auth context comp */}

    

    // </AuthContext.Consumer>

--------------------WITHOUT usecontext hook----------------------------------




HERE NEED TO ADD AS CONSUMER    ie.,  <AuthContext.Consumer>

const Navigation = (props) => {

  return (

    <AuthContext.Consumer>

      {(ctx)=>{

        return (<nav className={classes.nav}>

          <ul>

            {ctx.isLoggedIn && (

              <li>

                <a href="/">Users</a>

              </li>

            )}

            {/* {props.isLoggedIn && ( */}

            {ctx.isLoggedIn && (

              <li>

                <a href="/">Admin</a>

              </li>

            )}

            {ctx.isLoggedIn && (

              <li>

                <button onClick={props.onLogout}>Logout</button>

              </li>

            )}

          </ul>

        </nav>)

      }}  

      {/* will get data of auth context comp */}

    

    </AuthContext.Consumer>

  );

};

React: useReducer

 # useReducer

UseReducer used for  more complex forms, ex; step forms prev step to be passed to next step in form



const [state, dispatchFn]=useReducer(reducerFn,initialState, initFn)


1@state::: The state snapshot used in the component re-render/re-evaluation cycle 

2@dispatchFn::: A function that can be used to dispatch a new action (ie,trigger an update of the state)(ie., to update that above state snapshot) 

3@reducerFn::: (prevState, action)=>newState A function that is triggered automatically once an action is dispatched(via dispatchFn())-it receives that the latest state snapshot and should return the new, updated state. (ie, anytime new action is performed this function triggers) 

4@initialState::: initial state 

5@initFn::: A function to set the initial state programatically.


NOTE :


Adding Nested Properties As Dependencies To useEffect

In the previous lecture, we used object destructuring to add object properties as dependencies to useEffect().


const { someProperty } = someObject;

useEffect(() => {

  // code that only uses someProperty ...

}, [someProperty]);

This is a very common pattern and approach, which is why I typically use it and why I show it here (I will keep on using it throughout the course).


I just want to point out, that they key thing is NOT that we use destructuring but that we pass specific properties instead of the entire object as a dependency.


We could also write this code and it would work in the same way.


useEffect(() => {

  // code that only uses someProperty ...

}, [someObject.someProperty]);

This works just fine as well!


But you should avoid this code:


useEffect(() => {

  // code that only uses someProperty ...

}, [someObject]);

Why?


Because now the effect function would re-run whenever ANY property of someObject changes - not just the one property (someProperty in the above example) our effect might depend on.


Monday, October 10, 2022

React: UseEffect Types and working flow

 

useEffect(()=>{
  console.log("Effect Running");
});

Runs Every Time:



useEffect(()=>{
  console.log("Effect Running");
},[])

Runs Only Once:


3.

const Login = (props) => {
  const [enteredEmail, setEnteredEmail] = useState('');
  const [emailIsValid, setEmailIsValid] = useState();
  const [enteredPassword, setEnteredPassword] = useState('');
  const [passwordIsValid, setPasswordIsValid] = useState();
  const [formIsValid, setFormIsValid] = useState(false);

useEffect(()=>{
  console.log("Effect Running");
},[enteredPassword])


Effect Running for password:



const Login = (props) => {
  const [enteredEmail, setEnteredEmail] = useState('');
  const [emailIsValid, setEmailIsValid] = useState();
  const [enteredPassword, setEnteredPassword] = useState('');
  const [passwordIsValid, setPasswordIsValid] = useState();
  const [formIsValid, setFormIsValid] = useState(false);

useEffect(()=>{
  console.log("Pass Effect Running");
  return ()=>{ console.log("Pass Effect Cleanup")}
},[enteredPassword]);

Password Effect cleanup runs first (ie, return statement runs first)(first console msg loads onload webpage ie, pass effectr runnig and checkig validity)
order:







Saturday, October 8, 2022

React: Error Modal popup | Created div's in Index.html

 
 Modal popups is hidden by default,(coded inside nested div's ) so instead of using it in root div, 
created new divs, in index.html in public folder



Step 1 :In react project: in index.html added below lines

 <div id="backdrop-root"></div>

    <div id="modal-root"></div>

    <div id="root"></div>

ErrorModal code: 
pushing to above new created div's

import React from "react";
import ReactDOM from "react-dom";
import Card from "./Card";
import Button from "./Button";
import classes from "./ErrorModal.module.css";

const Backdrop = (props) => {
  return <div className={classes.backdrop} onClick={props.onConfirm} />;
};
const ModalOverlay = (props) => {
  return (
    <Card className={classes.modal}>
      <header className={classes.header}>
        <h2>{props.title}</h2>
      </header>
      <div className={classes.content}>
        <p>{props.message}</p>
      </div>
      <footer className={classes.actions}>
        <Button onClick={props.onConfirm}>Okay</Button>
      </footer>
    </Card>
  );
};

const ErrorModal = (props) => {
  return (
    <React.Fragment>
      /* imprt reactdom , it exists in package.json*/
      {ReactDOM.createPortal(
        <Backdrop onConfirm={props.onConfirm} />,
        document.getElementById("backdrop-root")
      )}
      {/* above   <Backdrop onConfirm={props.on is for closing popup oon clicking other than popup */}
      {ReactDOM.createPortal(
        <ModalOverlay
          title={props.title}
          message={props.message}
          onConfirm={props.onConfirm}
        />,
        document.getElementById("modal-root")
      )}
    </React.Fragment>
  );
};

export default ErrorModal;


Old code ErrorModal.js

import React from 'react';

import Card from '../Card';
import Button from '../Button';
import classes from './ErrorModal.module.css';

const ErrorModal = (props) => {
  return (
    <div>
      <div className={classes.backdrop} onClick={props.onConfirm} />
      <Card className={classes.modal}>
        <header className={classes.header}>
          <h2>{props.title}</h2>
        </header>
        <div className={classes.content}>
          <p>{props.message}</p>
        </div>
        <footer className={classes.actions}>
          <Button onClick={props.onConfirm}>Okay</Button>
        </footer>
      </Card>
    </div>
  );
};

export default ErrorModal;

Use Wrapper to avoid empty div's for grouping

After using wrapper instead of div, grouping ignored wrapper tag. 


created wrapper for ignoring grouping div, (for performance increase)

wrapper in app.js<Wrapper>...</Wrapper>



2. type : use empty wrapper <>....</>


3.type if empty tags wrapper wont work use below 
<React.Fragment> ....</React.Fragment>

Type 4:  import Fragment in react: then add tag <Fragment></Fragment>

Note
With Type 2,3,4  no need of using type 1 wrapper creation, 
Type 2,3,4 are inbuild, 
Type 1 is manually created for understanding, how wrapper works.

React sending data to parent from sibling node

1.parent component
2.passing to sibling black and parent node red
3.sibling comonetn



 

React: Sending data to siblings

 1.React form component

2.calling above compoent



note: passing data to sibling.

---------------------------------

 NewExpense.js file:  

<ExpenseForm onSaveExpenseData={onSaveExpenseDataHandler}></ExpenseForm>

---------------------------------

ExpenseForm.js: 

 props.onSaveExpenseData(expenseData); // calling one js file to other(newexpense.js)

 setEnteredTitle("");

 setEnteredAmount("");

 setEnteredDate("");  

};

---------------------------------

calling expenseform in app.js

 for appending form data to app.js file arr.

pushing data to parent node

props.onAddExpense(expenseData)  // lifting up date to parent app.js





Use Card styling for specific tag.

 Card.js

import React from "react";
import  classes from './Card.module.css';
const Card=(props)=>{
    return <div className={classes.card}>{props.children}</div>
   //For Dynamic below code cssClassName as ClassName default // return <div className={`${classes.card} ${props.cssClassName}`}>{props.children}</div>
}

export default Card Card.module.css
.card{
    background-color: yellow;
}

App.js
import Form from './Components/Form';
import './App.css';
import { useState } from 'react';
import UserList from './Components/UserList';
import Card from './Components/UI/Card';

function App() {
const data=[{"name":1,"age":2},{"name":11,"age":21}];

const [users,setusers]=useState([]);
const userlist=(res)=>{
setusers(prevuser=>{
  return [res,...prevuser];
})
}
  return (<Card > // <Card cssClass={classes.input}>
    <div className="App">
      <Form userdata={userlist}></Form>
      <UserList items={users}></UserList>
    </div></Card>
  );
}

export default App;