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
Post a Comment