Wednesday, November 30, 2022

usereducer

 import React, { useReducer, useState, useEffect } from "react";


const emailReducer = (state, action) => {
  if (action.type === "USER_INPUT") {
    return { value: action.val, isValid: action.val.length > 5 ? true : false };
  }
  if (action.type === "INPUT_BLUR") {
    return {
      value: state.value,
      isValid: state.value.length > 5 ? true : false,
    };
  }
  return { value: "", isValid: false };
};

const passwordReducer = (state, action) => {
  if (action.type === "PASS_IP") {
    return {
      value: action.value,
      isValid: action.value.length > 5 ? true : false,
    };
  } else if (action.type === "PASS_BLUR") {
    return {
      value: state.value,
      isValid: state.value.length > 5 ? true : false,
    };
  } else {
    return { value: "", isValid: null };
  }
};
const Login = () => {
  const [formIsValid, setFormIsValid] = useState(false);
  const [emailState, dispatchEmail] = useReducer(emailReducer, {
    value: "",
    isValid: null,
  });
  const [passState, dispatchpass] = useReducer(passwordReducer, {
    value: "",
    isValid: null,
  });

  //---------

  useEffect(() => {
    console.log("EFFECT RUNNING");

    return () => {
      console.log("EFFECT CLEANUP");
    };
  }, []);
  const { isValid: emailIsValid } = emailState;
  const { isValid: passwordIsValid } = passState;

  useEffect(() => {
    const identifier = setTimeout(() => {
      console.log("Checking form validity!");
      setFormIsValid(emailIsValid && passwordIsValid);
    }, 500);

    return () => {
      console.log("CLEANUP");
      clearTimeout(identifier);
    };
  }, [emailIsValid, passwordIsValid]);
  //---------------

  const emailChangeHandler = (event) => {
    dispatchEmail({ type: "USER_INPUT", val: event.target.value });
    console.log("dis em");
  };

  const validateEmailHandler = () => {
    dispatchEmail({ type: "INPUT_BLUR" });
  };

  const passwordHandler = (event) => {
    dispatchpass({ type: "PASS_IP", value: event.target.value });
  };
  const passwordBlurHandler = () => {
    dispatchpass({ type: "PASS_BLUR" });
  };
  const submitHandler = (event) => {
    event.preventDefault();
    // props.onLogin(emailState.value, enteredPassword);
  };

  return (
    <form onSubmit={submitHandler}>
      email:{emailState.isValid}
      pass:{passState.isValid}
      <div>
        {emailState.value}
        <label htmlFor="email">E-Mail</label>
        <input
          style={{ color: emailState.isValid ? "" : "red" }}
          type="email"
          id="email"
          value={emailState.value}
          onChange={emailChangeHandler}
          onBlur={validateEmailHandler}
        />
      </div>
      <input
        type="password"
        value={passState.value}
        onChange={passwordHandler}
        onBlur={passwordBlurHandler}
      />
      <button type="submit" disabled={!formIsValid}>
        submit
      </button>
    </form>
  );
};
export default Login;

Tuesday, November 29, 2022

React: usereducer

 LOGIN.js


Globally


const emailReducer = (state, action) => {

  if (action.type === 'USER_INPUT') {

    return { value: action.val, isValid: action.val.includes('@')};

  }

  if (action.type === 'INPUT_BLUR') {

    return { value: state.value, isValid: state.value.includes('@') };

  }

  return { value: '', isValid: false };

};


Inside Login Function

const [emailState, dispatchEmail] = useReducer(emailReducer, {

    value: '',

    isValid: null,

  });



const emailChangeHandler = (event) => {

    dispatchEmail({type: 'USER_INPUT', val: event.target.value});


    setFormIsValid(

      event.target.value.includes('@') && enteredPassword.trim().length > 6

    );

  };

  

    const validateEmailHandler = () => {

    dispatchEmail({type: 'INPUT_BLUR'});

  };

  

  

  

  const submitHandler = (event) => {

    event.preventDefault();

    props.onLogin(emailState.value, enteredPassword);

  };

  

  

  

  

  return (

    <Card className={classes.login}>

      <form onSubmit={submitHandler}>

        <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>

Monday, November 21, 2022

IMP: Debouncing : useEffect

 


useEffect(()=>{
const identifier=setTimeout(()=>{
setFormIsValid(
enteredEmail.includes('@') && enteredPassword.trim().length>6
)
},500)
return ()=>{
console.log('Cleanup');
clearTimeout(identifier);
}
},[enteredEmail,enteredPassword])


Thursday, November 17, 2022

React: Popup modal

Add backdrop to root for click
app.js

import logo from './logo.svg';
import './App.css';
import Modal from './modal/Modal';
import { useState } from 'react';

function App() {
  const [showPop,setShowPop]=useState(false)
  const subForm=()=>{
    setShowPop(true)
  }
  return (
    <div className="App">
     <button onClick={subForm}>show</button>
    {showPop && <Modal></Modal>}
    </div>
  );
}

export default App;
-----------------------------------------------------------
Modal.js
import React, { Fragment } from "react";
import classes from './Modal.module.css';

const Modal=()=>{
return <Fragment><div className={classes.backdrop}><div className={classes.modal}>
<header className={classes.header}>
    <h2>Error</h2>
</header>
<div className={classes.content}>this is body</div>
<footer className={classes.actions}>
    okay
</footer>
</div></div></Fragment>
}
export default Modal;
----------------------------------------------------------
.backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    z-index: 10;
    background: rgba(0, 0, 0, 0.75);
  }

.modal {
    position:fixed;
    top:30vh;
    left:10%;
    width: 80%;
    overflow: hidden;
    z-index: 100;
      }
     
.header{
background-color: gray;
padding: 1rem;
}

.header h2{
    margin: 0;
    color: white;
    }

.content{
padding: 1rem;
background-color: white;
}

.actions{
padding: 1rem;
display: flex;
justify-content: flex-end;
background-color: gray;
}


@media (min-width: 768px) {// used for adjusting size
    .modal {
      left: calc(50% - 20rem);
      width: 40rem;
    }
  }

 

Tuesday, November 15, 2022

htmlFor

<label htmlFor="username"> UserName </label>
<input id="username" type="text"/>

Friday, November 4, 2022

Http show error message on success or failure







 






import React, { useState } from 'react';


import MoviesList from './components/MoviesList';
import './App.css';

function App() {
  const [movies, setMovies] = useState([]);
  const [isLoading,setIsLoading]=useState(false);
  const [error, setError]=useState(null)

  // function fetchMoviesHandler(){
  //   fetch('https://swapi.py4e.com/api/films').then(response=>{
  //     return response.json();
  //   }).then(data=>{
  //     const transformedMovies=data.results.map(movieData=>{
  //       return {
  //             id: movieData.episode_id,
  //             title: movieData.title,
  //             openingText: movieData.opening_crawl,
  //             releaseDate: movieData.release_date,
  //       }
  //     })
  //     setMovies(transformedMovies)
  //   })
  // }
 async function fetchMoviesHandler(){
  setIsLoading(true);
  setError(null)
  try{
  const response= await fetch('https://swapi.py4e.com/api/film')
 
  // const data  = await response.json();  //to show exact syntax error
  if(!response.ok){
    throw new Error('Something went wrong')  //to show defined error message
  }
  const data  = await response.json();
    const transformedMovies=data.results.map(movieData=>{
      return {
            id: movieData.episode_id,
            title: movieData.title,
            openingText: movieData.opening_crawl,
            releaseDate: movieData.release_date,
      }
    })
    setMovies(transformedMovies)
    // setIsLoading(false); moved to bottom
  }catch (error){
   setError(error.message);
  }
  setIsLoading(false);}
 
return (
  <React.Fragment>
    <section>
      <button onClick={fetchMoviesHandler}>Fetch Movies</button>
    </section>
    <section>
      {!isLoading && movies.length>0 && <MoviesList movies={movies} />}
      {!isLoading && movies.length===0 && !error && <p>No movies found</p>}
      {!isLoading && error && <p>{error}</p>}
      {isLoading && <p>Loading...</p>}
    </section>
  </React.Fragment>
);
}

export default App;

Wednesday, November 2, 2022

React: class component

 import {Component } from 'react'; //-------------added this line

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

class User extends Component{
  render(){
    return <li className={classes.user}>{this.props.name}</li>;
  }
}
//----------commented below and added above
//const User = (props) => {
 // return <li className={classes.user}>{props.name}</li>;
//};

export default User;

React useMemo() performance

 https://www.w3schools.com/react/react_usememo.asp






usememo memorize the value and uses it for every execution if no change is done to value, 

it compares prev state with new state, if no change found then usememoze value is used directly 

React: Usecallback & usememo--To improve performance


  

v:157: usecallback

use it when required instead of running every time. 

(instead of running all the states,or all data in function, we can control it with usecallback, triggered only when requeired, check below code, 2 buttons added first click on paragraph button tht doesnt work, when clicking on first buttong and then clik on 2nd it works and it triggers, check with console)

function App(){

const [showParagraph, setShowParagraph]=useState(false);

const [allowToggle, setAllowToggle]=useState(false);


const toggleParagraphHandler=useCallback(()=>{

if(allowToggle){

setShowParagraph((prevShowParagraph)=>!prevShowParagraph);

}

},[allowToggle]);


const allowToggleHandler=()=>{

setAllowToggle(true);

}


return <Fragment>

<Button onClick="allowToggleHandler">Allow Toggling</Button>

<Button onClick="toggleParagraphHandler">Toggle Paragraph</Button>

</Fragment>

}