ReactJS (overall) (general)

GENERAL NOTES


React is built by Jordan Walke, a software engineer at Facebook, who founded the library in 2011.

===============================================================

NAMING - JAVASCRIPT AND REACT:

... is "spread operator"

"Arrow Functions" which are => like rest of Javascrpt a.k.a. lambda a.k.a. anonymous functions
Syntax: "Arrow Functions" point at parenthesis rather than braces.  

===============================================================

OVERALL: WHY REACT?

High performance reinforced by Virtual DOM

By virtualizing and keeping DOM in memory, React grants outstandingly fast rendering capacities with all view changes readily reflected in the virtual DOM. The specialized diff algorithm juxtaposes former and existing virtual DOM states, calculating the most efficient way to apply new changes without requiring too many updates. A minimum number of updates is then introduced to achieve the fastest read/write time, which results in an overall performance boost.

DOM changes make systems slow, and by virtualizing DOM, those changes are minimized and optimized intelligently. All the virtual DOM manipulations happen “behind the scenes,” i.e., internally and autonomously, which also allows for significant save hardware resource-consumption rates (CPU power and battery in mobile devices, for instance, which should give you a hint as to when to use React.js as well).

 
So think of React as Component State --> DOM --> New Component State --> New DOM

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

Purpose of creating separate web design elements and components (anything from buttons and labels to grids and interactive features).

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

REACT VS. OTHERS

 React uses Virtual DOM.  SolidJs does not.

 Two-way data binding (Angular) vs one-way data flow (React/Flux).
   In React, data flows one way: from owner to child. So only one way binding.

 Unlike Vue and Angular, there is no extra HTML attributes (JS is “crammed” into HTML)

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

REACT HISTORY

React Component Types
 1) Class - hold state, uses lifecycle methods
 2) Functional - stateless, never use lifecycle methods

old way is classes . new way is hooks.

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

REACT'S Component Lifecycle Methods:
   1) Initialization (set up the state and the props),
   2) Mounting (component is created and inserted into the DOM) (with componentWillMount() then componentDidMount(),
   3) Updating (re-rendering because state changed) (shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate()),  
   4) Unmounting (componentWillUnmount()) .

==============================================

INSTALL OR DEPENDENCIES

reactjs.org

React developer tools for Chrome => chrome://extensions => turn on "Allow access to file URLs"
  so can access local files.  Command + Shift + J to see React components on the web page.

Firefox developer tools for React => right-click and inspect to see the React components

Visual Studio Code Editor -> Theme => Night Owl => add night owl extension

https://react.new => sign in with Github or CodePen => so is code sandbox

if new app: start npx creat-react-app react-app
if have existing react project, then also installs all dependencies:  reach-app npm install
  then:   npm start

Babel website to translate Javascript ECMAScript 2015+ back to older Javascript:  babeljs.io

Node Js: nodejs.org
NPM : is a installing tool

https://caniuse.com

===============================================================
StrictMode

 ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  );
 
===============================================================

In index.html, add 2 links (React and React DOM) to <head> in <script> tags

then in <body> you can add to <script type="text/javascript">,
  let ul = React.createElement("ul", { style: { color: "blue" } },
    React.createElement("li", null, "Monday"),
    React.createElement("li", null, "Tuesay"),
    React.createElement("li", null, "Wednesday"));

  ReactDOM.render(
    ul,
    document.getElementById("root")
  );
  </script>

===============================================================

so was: <script type="text/javascript">
now: <script type="text/babel">

===============================================================

JS/X, which stands for JavaScript XML. Similar to HTML. XML inside JS together.

JSX changes things instead of needing React.createElement, by instead just using tags.
  But it is still is inside ReactDOM.render
JSX has <ul> and <li> tags.  JSX understands variables in braces such as { name } .

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

React wants to render only a single component at a time.  Multiple gets error.
Fix by making function to hold the multiple components. Then use the function name in the render to fix things.

2 reasons for “JSX expressions must have one parent element”
   1) return has 2 things returned
   2) you typed 2 return statements

3 Ways To Fix the “JSX expressions must have one parent element” Error
    1) Using a Div Wrapper
    2) Using a Fragment (<> and </>)
    3) Using React.Fragment component
  PS- all these are done inside the JSX of the function App() inside the return { }

===============================================================
Images
 
 <img src="<<url>>>" alt="image alt name" height={100} />

OR
 drag image to be local in folder and :
 <img src="./restaurant.jpeg" alt="image alt name" height={100} />

===============================================================

Container Presentation Pattern
  1) Container - state, parent flows to child presentation, never shows, collects data
  2) Presentation - present state

Staple components - uses lifecycle methods (willMount (being rendered), render, didMount, willUnmount)
Node.Js (express API or happy API or serverless azure functions)

Event Handing
  event handlers

==============================================

App.js which is the starting point
  import Search from "./components/Search"
  import AddAppointment from "./components/AddAppointment"

  function App() {
    <AddAppointment />
    <Search />
    <ul className="divide">
       {appointmentList
           .map(appointment => (
                 <AppointmentInfo key={appointment.id}
                    appointment={appointment}
                 />
               ))
       }
     </ul>
  }
  export default App;

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

AppointmentInfo.js file which returns JS/X
  import {BiTrash} from "react-icons/bi"
  const AppointmentInfo = () => { return {
           <li classname"px-3">
              <button type="button" <BiTrash /> </button>
              ...
           </li>} }
  export default AppointmentInfo

==============================================

useState Hook

  import {useState} from 'react';

  const AddAppointment = () => {
    let [toggleForm, setToggleForm] = useState(false)
    return {
        <div>
           ....
        </div} }  
 
----------------------------------------------
  Example 2:
 
  import {useState} from 'react';
 
  function App() {
    const [emotion, setEmotion] = useState("happy");
    return (
       <div className="App">
         <h1> Current emotion is (emotion)</h1>
         <button onClick={() => setEmotion("sad")}> Sad </button>
         <button onClick={() => setEmotion("excited")}> Excited </button>
       </div>
    );
  }
 
  export default App;

----------------------------------------------
   Example 3:

    toggle variable turns off the drop down contents


  import {useState} from 'react';

 const DropDown = ({ toggle }) => {
   if (!toggle) { return null; }
    
   return (
      <div ....
        </div} }
  }    



============================================================================================
useEffect Hook (used for data searching or manually changing DOM when components are result of these operations) and useCallback hooks:

----------------------------------------------
  Calls only on inital value when first renders (so has nothing):
   WAY 1 - useEffect(() => { console.log('It is ${secondary} around here!'); });
   WAY 2 - useEffect(() => { console.log('It is ${secondary} around here!'); }, []);
----------------------------------------------
  Calls whenever it changes:
   useEffect(() => { console.log('It is ${secondary} around here!'); [secondary]});
--------------------------------------------------------------------------------------------
  Calls whenever it OR other variable changes. Dependency Array.
   useEffect(() => { console.log('It is ${secondary} around here!'); [emotion, secondary]});
--------------------------------------------------------------------------------------------
  Data Fetching with useEffect and useState:

  WAY 1 -
    const [data, setData] = useState(null);  
    useEffect(() => {
     fetch('<<< URL >>>')
       .then((response) => response.json())
       .then(setData);
      }, []);
   if (data)
     return ( <pre>{JSON.stringfy(data, null, 2)}</pre> );
   return <h1>Data</h1>;  

  WAY 2 -
    const [data, setData] = useState(null);  
    const [error, setError] = useState(null);
    const [loading, setLoading] = useState(false);
    useEffect(() => {
     fetch('<<< URL >>>')
       .then((response) => response.json())
       .then(setData)
       .then(() => setLoading(false))
       .catch(setError);
      }, []);
   if (loading) return <h1>Loading...</h1>;
   if (error) return <pre>{JSON.stringify(error)}</pre>;
   if (!data) return null;
   return ( <GitHubUser name={data.name} location={data.location} avatar={data.avatar_url});

  WAY 3 -

App.js
  import {useState, useEffect, useCallback} from 'react';

  function App() {
      let [appointmentList, setAppointmentList] = useState([]);
      const foreach = useCallback(() => {
        fetch('./data.json')
          .then(response => response.json())
          .then(data => { setAppointmentList(data)
        });
      }, [])
      useEffect(() => { fetchData() }, [fetchData])
      ...  

============================================================================================
useReducer Hook

import {useReducer} from "react";

function App() {
   const [checked, setChecked] = useReducer((checked) => !checked, false);
   return (
     <div className="app">
       <input type="checkbox" value={checked} onChange={setChecked}/>
       <label> { checked ? "checked" : "not checked" } </label>
     </div>
   );
}

============================================================================================
useRef Hook  and uncontrolled components (outside of state). useRef do not rerender. Must keep looking at current.value.

import {useRef} from "react";

function App() {
   const txtTitle = useRef();
   const hexColor = useRef();
   const submit = (e) => {
     e.preventDefault();
     alert('${txtTitle.current.value}, ${hexColor.current.value}');
   };
   return (
     <form onSubmit={submit}>
       <input type="text" placeholder="color title..." ref={txtTitle}/>
       <input type="color" ref={hexColor}/>
       <button> ADD </button>
     </form>
   );
}

============================================================================================
useState Hook  and controlled form.

import {useState} from "react";

function App() {
   const [title, setTitle] = useState("");
   const [color, setColor] = useState("#000000");
   const submit = (e) => {
     e.preventDefault();
     alert('${title}, ${color}');
     setTitle("");
     setColor("#000000");
   };
   return (
     <form onSubmit={submit}>
       <input type="text" placeholder="color title..." value={title} onChange={(event) => setTitle(event.target.value) }/>
       <input type="color" value={color} onChange={(event) => setColor(event.target.value) }/>
       <button> ADD </button>
     </form>
   );
}

============================================================================================
Custom Developer-Defined Hook   
     you combine hooks into newer hooks using useState and useEffect

import {useState} from "react";

function useInput(initValue) {
   const [value, setValue] = useState(initValue);
   return [ { value, onChange: (e) => setValue(e.target.value) }, () => setValue(initValue) ];
}

function App() {
   const [titleProps, resetTitle] = useInput("");
   const [colorProps, resetColor] = useInput("#000000");
   const submit = (e) => {
     e.preventDefault();
     alert('${titleProps.value}, ${colorProps.value}');
     resetTitle();
     resetColor();
   };
   return (
     <form onSubmit={submit}>
       <input {..titleProps} type="text" placeholder="color title..." />
       <input {..colorProps} type="color" />
       <button> ADD </button>
     </form>
   );
}

 Example of Custom Hook:
   1) useDataSource which loads data from a server or from local storage.
   2) useResource which loads any server-side resource inside any component.

============================================================================================

Delete records:

AppointmentInfo.js
  const AppointmentInfo = ({appointment, onDeleteAppointment }) => {
   return (
     ...

     <button onClick={ () => onDeleteAppointment(appointment.id)} type="button"
       ... </button>
     ...
   )
  }

App.js
  function App() {
    <AddAppointment />
    <Search />
    <ul className="divide">
       {appointmentList
           .map(appointment => (
                 <AppointmentInfo key={appointment.id}
                    appointment={appointment}
                    onDeleteAppointment={
                      appointmentId => setAppointmentList(appointmentList.filter(appointment =>
                          appointment.id === appointmentId))
                    }
                 />
               ))
       }
     </ul>

============================================================================================

Filter:

Search.js
    const Search = ({query, onQueryChange}) => {
         ...
         <input onChange={(event) => onQueryChange(event.target.value)}}
         ...

App.js
  function App() {
    let [queryBy, setQueryBy] = useState("");

    const filteredAppointments = appoints.filter(
         item => {
             return (
                item.petName.toLowerCase().includes(query.toLowerCase()) ||   
                item.ownerName.toLowerCase().includes(query.toLowerCase()) ||
                item.aptNotes.toLowerCase().includes(query.toLowerCase())
             )
         }
    )
    ...
     <Search query={query}
             onQueryChange={myQuery => setQuery(myQuery)} />
    ...


============================================================================================
For sorting, go ahead and do filtering first.

Sort:


App.js
  function App() {
    let [sortBy, setSortBy] = useState("petName");
    let [orderBy, setOrderBy] = useState("asc");
    
    const filteredAppointments = appoints.filter(
         item => {
             return (
                item.petName.toLowerCase().includes(query.toLowerCase()) ||   
                item.ownerName.toLowerCase().includes(query.toLowerCase()) ||
                item.aptNotes.toLowerCase().includes(query.toLowerCase())
             )
         }
    ).sort((a, b) => {
        let order = (orderBy === 'asc') ? 1 : -1;
        return (
          a[sortBy].toLowerCase() < b[sortBy].toLowerCase()
            ? -1 * order : 1 * order
        )
    })


    ...
     <Search query={query}
             onQueryChange={myQuery => setQuery(myQuery)}
             orderBy={orderBy}
             onOrderByChange={myQuery => setOrderBy(myQuery)}
             sortBy={sortBy}
             onSortByChange={myQuery => setSortBy(myQuery)}
     />
    ...
 

Search.js
    const Search = ({query, onQueryChange, sortBy, onSortByChange, orderBy, onOrderByChange}) => {
         ...
         <input onChange={(event) => onQueryChange(event.target.value)}}
         ...
 
         <DropDown toggle={toggleSort}
            sortBy={sortBy}
            onSortByChange={mySort => onSortByChange(mySort)}
            orderBy={orderBy}
            onOrderByChange={myOrder => onOrderByChange(myOrder)}

 const DropDown = ({ toggle, sortBy, onSortByChange, orderBy, onOrderByChange }) => {
   if (!toggle) { return null; }
    
   return (
      <div onClick={()=> onSortByChange('petName') ...x4 more spots including asc and desc ....
     
        </div} }
  }

============================================================================================

the spread operator in Javascript is ... and is a newer feature that will pass all the information
  in formData plus the OwnerName using the event.target.value
 
  <input onChange={(event) => { setFormData({ ...formData, ownerName: event.target.value})}}
         value={formData.ownerName}

============================================================================================
the spread operator in Javascript can also append

  <AddAppointment={myAppointment => setAppointmentList([...appointmentList, myAppointment])}
 
============================================================================================

reducer is a function in Javascript is misnamed which is actually an array that you can add a sequence of elements to the array.

   lastId = { appointmentList.reduce((max, item) => Number(item.id) > max ? Number(item.id): max, 0)}

============================================================================================

PARAMETER (a.k.a. PROPERTIES)

function Footer(params) { return ( <footer> <p> Copyright {params.year} </p> </footer> ); }
function App() { return ( <div> <Footer year={new Date().getFullYear()}/> </div> ); }

============================================================================================

DESTRUCTORING

Example 1:
const [firstCity, second] = ["Tokyo", "Tahoe", "Bend"]
console.log(firstCity);
console.log(second);

Example 2:
In index.js :
 ReactDOM.render(
    <React.StrictMode>
      <App library="React"/>
    </React.StrictMode>,
    document.getElementById("root")
  );

Old in App.js:
function App({props}) {
   return (
     <div className="App">
       <h1> Hello from {props.library}</h1>
     </div>
   );
}

New in App.js:
function App({library}) {
   return (
     <div className="App">
       <h1> Hello from {library}</h1>
     </div>
   );
}

============================================================================================

GraphQL site (for fake data):
https://snowtooth.moonhighway.com/

CHOOSING A FORM LIBRARY (for custom hooks)

formik.org
react-hook-form.com
usehooks.com

============================================================================================

RENDER PROPS

function List({data, renderItem}) {
   return !data.length ? renderEmpty : (<ul>{data.map((item) => (<li key={item.name}> {renderItem(item)} </li>))}</ul>);
}

function App() {
  return (
   <List data={tahoe_peaks}
     renderEmpty={<p>This list is empty.</p>
     renderItem={(item) => (
        <>
          {item.name} - {item.elevation} ft.
        </>
     )}
   />
 );

===============================================================
OBTAIN DATA

https://axios-http.com/

===============================================================
MOVE PAGE TO PAGE

Move from page to page - www.reactrouter.com

===============================================================
 DEPLOY

app.netlify.com - does deployment for the BUILT location of the react in finished/react-app
 
==============================================
Improve list types so small and large of each entity

Layout Components
  Split-screen Component
  List Component

Modal components
  Modal Component
  e.stopPropagation() - use this so does not trigger enter that ends the modal

Container Components
  Container Component - misnomer - loads data of children object

  Current User Loader Component
    React.Children.map(children, child => {
          if (React.isValidElement(child)) {
            return React.cloneElement(child, {user}
          }
      }

    export const UserInfo = ({ user }) => {
       const { name, age, hairColor, hobbies } = user || {};
       return user ? (
         <>
         <h3>{name}</h3>
         <p>Age:{age} years</p>
         <h3>Hobbies</h3>
         <ul>
            {hobbies.map(hobby => <li key={hobby}>{hobby}</li>)}
         </ul>
         </>
        ) : <p>Loading...</p>;
    }

  User Loader Component

  Resource Loader Component - misnomer - seems to be a generic loader for entities

  Data Source Component - *** better generic loader ***
    allows you to load data from local storage instead of from a server.
    getDataFunction - passes data to child components  

==============================================

Uncontrolled Components
  the component itself tracks its own state
  releases data only when event occurs

Controlled Components
  all state is passed in as props (useState hook)
  generally prefer - more reusable, easier to test, better for interactive stuff
  usually OnChange parameter
  useEffect to listen for changes
  bunch of useState as const at top for each of the fields
  A controlled form keeps track of values for each input using a useState hook, while an uncontrolled form does not.
  Each input in a controlled form has an onChange handler that updates state variable.

Uncontrolled Forms
   3 input types are text, number, and submit

Uncontrolled Modals
   The parent component has no way to make the modal display itself.

Controlled Modals
   has shouldShow property
   has onRequestClose event that will fire on the onClick for each of the controls
   has children
   so parent handles the things about the modal

==============================================

 Uncontrolled onboarding data - breaks down into fields into steps that user is suppose to fill in
   onFinish event

 Controlled onboarding flow - breaks down into fields into steps that user is suppose to fill in
   onFinish event
   currentIndex prop (new)
   onNext prop (new)
   parent does the Goto Next instead of component
   Ensures the steps are in proper order, tracks data, and is an easy way to reset the onboarding process.
   Allows the parent app component to have more control over what is displayed
     
  <ControlledOnboardingFlow currentIndex={currentIndex} onNext={onNext}>
   <StepTwo />
     {onboardingData.age >= 62 && <StepThree />}
   <StepFour />
  </ControlledOnboardingFlow>

==============================================

Higher-Order Components (HOCs)
  HOCs that returns another component instead of JSX
  HOCs are just functions
  Used for sharing complex behavior OR add functionality to old components
  The purpose of the HOC called with user is to load a specific user from a server.

  Print props
  Load data
  Modify data
  Create forms
 
  User to "Data" for generics
  const resourceProps = {
     [resourceName]: data,
  }

==============================================

Custom Hooks
  useCurrentUser
  useUser
  useResource
  useDataSource

==============================================

Functional Programming
  1) minimizes mutation and state change
  2) keeps functions independent of external data
  3) treats functions as first-class citizens

Applications of FP in React:
  1) Controlled components
  2) Function components
  3) HOCs
  4) Recursive components
  5) Partially-Applied Components
  6) Component Composition

==============================================
Recursive Components
 
Component Composition

Partially-Applied Components

==============================================

React Native

React Native comes in as a true game-changer that opens up for you native and hybrid mobile app development for iOS and Android. Naturally, you lose certain code reusability opportunities, but only in favor of proper native performance and system management.

Comments

Popular posts from this blog

Upgrading to .NET8 from desktop versions 4.8.X

GHL Chat Bots for Webpage

GHL > Set website so shorter URL address