React Fundamentals

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 18

REACT-SMILGA-S01-03-FUNDAMENTALS

REACT DEFINITION
NODE VERSION
REACT DEVELOPER TOOLS - CHROME EXT.
CREATE REACT APP
OPEN VSCODE TERMINAL SHORTCUT
DRAG & DROP YOUR REACT PROJECT FOLDER INTO THE TERMINAL
INSTALL CREATE REACT APP
FUNDAMENTALS
Folder Structure
REMOVE CREATE-REACT APPS BOILERPLATE
APP.JS
APP.CSS / INDEX.CSS
INDEX.JS
TOGGLE VSCODE SIDEBAR
REACT COMPONENTS
IMPORTS
ES7+ React/Redux/React-Native snippets
rafce (Arrow FN - w/ Export) / rfce (Regular FN - w/ Export)
JSX RULES
<React.Fragment> - RETURNING MULTIPLE ELs - return <>...rest of the return</>;
NESTING COMPONENTS
IMAGES - src folder = optimized.
JSX - CSS (inline styles)
JSX - JS = { } ({ } - Means Inserting JS)
PROPS
Props - Somewhat Dynamic Setup
PROPS DATA FLOW (= From Where Component is Injected to Actual Component
FN)
CHILDREN PROP - useful when an Instance of a Component (= Where its Injected)
needs to Render Diff. HTML than Other Instances
In Actual Component > const { img, title, author, children } = props;

{children}
</article>

OBJECTS CANT BE RENDERED DIRECTLY IN REACT - use SPREAD (...)


{books.map((book) => { return <Book {...book} key={book.id} />; })}
KEY PROP - typically it's going to be an ID. <li key={id}>
EVENTS - Most common: onClick, onSubmit, onChange (input change)
BTN TYPES & EVT TYPES - “SUBMIT” (use onSubmit ), “BUTTON” (use onClick)
EVT HANDLERS - Referenced FN vs Anonymous FN
*Inside EVT L’ - can either have a Reference to a Handler OR an Anonymous FN
COMPONENTS ARE INDEPENDENT BY DEFAULT - Prevents A lot of Hoops to Jump
thru - to Manipulate DOM
PROP DRILLING -Prop drilling is the unofficial term for passing data through several
nested children components - *Can ONLY Pass PROPs = DOWN
INVOKING FNs STRAIGHT AWAY PROBLEM - bc of Parentheses
*Invoke Straight away = “getBook(id)” vs *Reference to a FN = “getBook” -
*Solutions: 1 Wrap Handler in another FN - that is Only Referenced in EVT/L’
2. Wrap Handler in Anon. FN (Inside EVT/L)
ES6 MODULES
*Export/Import a NAMED EXPORT” -
*Export/Import a DEFAULT EXPORT” -
IMG FOLDER IN “SRC” FOLDER - (= AUTO-OPTIMISATION BY REACT)
BUILD PRODUCTION APP
EACH CHAPTER HAS NOTES COMPLETED IN HIS GITHUB REPO
https://github.com/john-smilga/react-course-v3/blob/main/01-fundamentals/README.m
d

REACT DEFINITION
*”A JS Library for building UIs”

NODE VERSION
*Always use the LTS Ver. (= Stable) - bc it Takes a While for Other Dependencies, etc to
Catch Up to the Latest (Bleeding Edge) Ver.

REACT DEVELOPER TOOLS - CHROME EXT.


*Add so can use the “COMPONENTS” TAB in CHR. D/V TOOLS
- For Debugging Components

CREATE REACT APP


Create React App is a development environment that helps to speed up the
development process by letting developers focus on their code instead of
configuring build tools. Under the hood, Create React App uses a third-party build
tool called webpack to handle its core functionalities.
*We will use this in the Early Part of the Course bc you will come across it on the Job -
BUT “VITE” is the goto these days.

https://create-react-app.dev/docs/getting-started/

*These days you don’t Install “Create React App” & then Create Instance of React -
instead you use the NPX CMD (Node Package Executor)
NPX is a package executer, and it is used to execute javascript packages directly,
without installing them.

OPEN VSCODE TERMINAL SHORTCUT


> ctrl + ~
DRAG & DROP YOUR REACT PROJECT FOLDER INTO THE TERMINAL
*This will A/M ensure you are located at Project ROOT for - OR Open Project DIR &
then Open Terminal

1st INSTALL CREATE REACT APP


*1st Browse to the Install Location you desire
*You use this CMD EVERY TIME you want to Create a New REACT INSTANCE:
(npx means np EXECUTE - so we are not Installing “create react” SW - just Executing
it)
> npx create-react-app yourAppName

*If you get an Error - type: npx create-react-app@latest yourAppName

2nd NPM START


*Starts the D/V Server
*If successful you should see the react LOGO
In VS CODE > Navigate to the Project DIR > npm start

NPM BUILD
*Bundles your APP into Static Files for Production
> npm run build

CTRL/C
*To Stop the Server > npm start i (To restart it)

FUNDAMENTALS

Folder Structure

node_modules Contains all dependencies required by the app. There are heaps in
here bc - eg. Our Depenedencies have Dependencies.
Main dependencies also listed in package.json
public Contains static assets including index.html (page template)
Index.html, title, fonts, css, favicon
*In the index.html there is a <div id="root"> - our entire app gets INJECTED here
From our Working DIR (‘src’)

src Our working DIR


*src/index.js is the JavaScript entry point.
*There is no restrictions on how you structure this DIR - BUT “index.js” - MUST be there

.gitignore Specifies which files source control (Git) should ignore

package.json Every Node.js project has a package.json and it contains info about our
project, for example list of dependencies and scripts
*Also called “manifest File”

package-lock.json A snapshot of the entire dependency tree

README The markdown file where you can share more info about the project for
example build instructions and summary

REMOVE CREATE-REACT APPS BOILERPLATE


*We removed “src” DIR, etc - so that we can build them from Scratch - VID 16 - 1:00
= Removed “src” DIR & Recreated it Manually (along w/ “index.js”)
- Got an Error after this so: CTRL/C to Stop Server & npm start

*In 2nd Project:


*Removed in “index.js” - reportWebVitals() (its for Analytics) & its Import Line
*Removed in “app.js” - import logo (the React Logo itself)….Line
- ALL JSX (between Return ( ) ) - in function App()
- import…./App.css;
*Removed “App.css”, App.test.js, logo.svg, reportWebVitals.js, setupTests.js

- So: ONLY App.js, index.css & index.js Remain in “src” DIR

APP.JS
*App.js (= Convention to name it this) - is where all our Components will meet
*Import it in “index.js” > import App from './App';
APP.CSS / INDEX.CSS
*Part of “CREATE-REACT” Boilerplate - they are for Splitting up your CSS - BUT they
compile to the SAME PLACE - so = CONFLICTS can occur
*We REMOVED App.css

INDEX.JS
*This Injects the HTML into index.html
*Our Backroads Project - index.js:

// IMPORTs
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

import App from './App';

// ROOT EL - TO Render the APP INTO


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

TOGGLE VSCODE SIDEBAR


> ctrl/b

REACT COMPONENTS
*Are Created using FNs - so think “FN” when you think of a Component
*Start with capital letter
*Must return JSX (html)
*Close TAGs - either by: <Greeting></Greeting> OR <Greeting />
IMPORTS
*JS Files = DONT Need Extension
// These are Libraries - so DONT Have to Specify the PATH (Only = Library Name)
import React from 'react';
import ReactDOM from 'react-dom/client';
// But Our Own Assets - Specify the PATH
import './index.css';

Typical Component
const Greeting = () => {
return <h2>My First Component</h2>;
};

MY FIRST COMPONENT
*In index.js:

// Imports - these are From REACT ITSELF


import React from 'react';
import ReactDOM from 'react-dom/client';

function Greeting() {
return <h2>My First Component</h2>;
}

// The ROOT <div> where ALL JSX gets INJECTED INTO (Render to)
const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(<Greeting />);

ES7+ React/Redux/React-Native snippets


*Install this Ext. for - Autocomplete Shortcuts
*Here are the DOCs for the S/Cuts
https://github.com/ults-io/vscode-react-javascript-snippets/blob/HEAD/docs/Snip
pets.md
*2 Main 1s: rafce (Arrow FN - w/ Export)
rfce (Regular FN - w/ Export)
*Auto Snippets Uses will use either Uppercase OR Lowercase for the Component
Name - Depending on if you named its Parent File Starting w/ an U/Case or a L/Case

JSX RULES
*Must only return single element (one parent element)
*semantics - section/article - his recc (save you hassles later)

*Fragment - let's us group elements without adding extra nodes


return <React.Fragment>...rest of the return</React.Fragment>;
// OR shorthand
return <>...rest of the return</>;

*Also = Good for Returning ADJACENT EL’s (Which Normally isnt allowed)

*camelCase Naming Convention - eg. for HTML Attri’s: onClick, etc


*”className” - Instead of “class”
*Close EVERY TAG - eg <img> - MUST BE: <img />
*Use () after Return - OR ensure Opening TAG is on Same Line as Return K/Word
function Greeting() {
return (
<div className='someValue'>
<h3>hello people</h3>
)

NESTING COMPONENTS
*In React we Nest Components
*We can then Nest Components in those also

function Greeting() {
return (
<div>
<Person />
<Message />
</div>
);
}

// Components to be Nested
const Person = () => <h2>john doe</h2>;
const Message = () => {
return <p>this is my message</p>;
};

IMAGES
*external images (hosted on different server) - just need an url
*local images (public folder) - less performant
*local images (src folder) - better solution for assets, since under the hood they
get optimized.

JSX - CSS (inline styles)


*Not recc’d - BUT some Libraries - eg. Sliders, etc will use some Inline Styles (so if
trying to Change some Styles & not working = Check there)
*Need to Wrap the CSS PROPs OBJ in { } (this tells JSX we are using JS)
*Replace CSS HYPHENs w/ CAPs

const Author = () => {


const inlineHeadingStyles = {
color: '#617d98',
fontSize: '0.75rem',
marginTop: '0.5rem',
};
return <h4 style={inlineHeadingStyles}>Jordan Moore </h4>;
};
JSX - JS
* { } (this tells JSX we are using JS)
*value inside { } - must be an expression (returns a value), can't be a statement
- eg.
title = 'Interesting Facts For Curious Minds';
NOT let x = 6;

<h2>{title}</h2>
<p>{6 + 6}</p> // works - bc it Returns a VAL

PROPS
*Props allow you to pass data from one component to another, as parameters.
*The Props object (= an OBJ Received as PARAMs), it is a convention to call it
props
= passed in as key/value pairs
*If the prop exists it will return value, otherwise no value

Props - Somewhat Dynamic Setup


const firstBook = {
author: 'Jordan Moore',
title: 'Interesting Facts For Curious Minds',
img: './images/book-1.jpg',
};
const secondBook = {
author: 'James Clear',
title: 'Atomic Habits',
img: './img-1.jpg',
};

function BookList() {
return (
<section className='booklist'>
<Book
author={firstBook.author}
title={firstBook.title}
img={firstBook.img}
/>
<Book
author={secondBook.author}
title={secondBook.title}
img={secondBook.img}
/>
</section>
);
}

const Book = (props) => {


const { img, title, author } = props;
return (
<article className='book'>
<img src={img} alt={title} />
<h2>{title}</h2>
<h4>{author} </h4>
</article>
);
};

*Alternatively, can just Destr. PROPs Inside PARAM ()


const Book = ({ img, author, title }) => {

PROPS DATA FLOW


*React Props are like function arguments in JavaScript and attributes in HTML.
To send props into a component, use the same syntax as HTML attributes
The component receives the argument as a props object (Key: Value - Pairs) - thus can
Access PROPs VALs using DOT SYNTAX (.author)

*DATA FLOW OF PROPS=


1. FROM: The TAG Where the Component is Injected to - to
2. TO: The Actual Component (FN) (Receives the PROPs OBJ as an Argument)

function BookList() {
return (
<section className='booklist'>
<Book author={myObj.author} title={myObj.title} img={myObj.img} />
</section>
);
}
const Book = (props) => {
console.log(props);
return (
<article className='book'>
<img src={props.img} alt={props.title} />
<h2>{props.title}</h2>
<h4>{props.author} </h4>
</article>
);
};

CHILDREN PROP
*This is a SPECIAL NAMED PROP Called “children” is ALWAYs Passed Inside
PROPs OBJ
*It Renders E/Th you include between the opening and closing tags when
invoking a component.
*A Use case of this is if we want a <p> & <btn> to Appear in 1 “Book” Component but
not in the Other one - by Embedding {children} in the “Book” Component, that means
Even though the Same “Book” Component Template is being used for Both “Books” - it
will Render Whats Between the Opening & Closing TAGs for ea. Instance of “Book”
*So by Putting the Extra JSX Markup in the 1st “Book” Component - bc we embed
{children} in the “Book” Components Templates - what ever is in between the Opening &
Closing TAGs for ea. Given “Book” Component will be Rendered (thus = Different
Content)
const Book = (props) => {
const { img, title, author, children } = props;

Ex:
function BookList() {
return (
<section className='booklist'>
<Book
author={firstBook.author}
title={firstBook.title}
img={firstBook.img}
>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Itaque
repudiandae inventore eos qui animi sed iusto alias eius ea sapiente.
</p>
<button>click me</button>
</Book>
<Book
author={secondBook.author}
title={secondBook.title}
img={secondBook.img}
/>
</section>
);
}

const Book = ({ img, title, author, children }) => {


// rest of the logic
};
const Book = (props) => {
const { img, title, author, children } = props;
console.log(props);
return (
<article className='book'>
<img src={img} alt={title} />
<h2>{title}</h2>
<h4>{author} </h4>
{children}
</article>
);
};
OBJECTS CANT BE RENDERED DIRECTLY IN REACT
*So if Passing an OBJ - use SPREAD (...) to Destr. OBJ

function BookList() {
return (
<section className='booklist'>

// “books” = ARR containing OBJs (“book” is ea.OBJ)


{books.map((book) => {
return <Book {...book} key={book.id} />;
})}
</section>
);
}

// The SPREADED OBJs are Passed as “props”


const Book = (props) => {
const { img, title, author } = props;
return (
<article className='book'>
<img src={img} alt={title} />
<h2>{title}</h2>
<h4>{author} </h4>
</article>
);
};

KEY PROP
*When you Render items in React, React wants to keep track of those
items.
So we need to provide a unique value and set it equal to a key prop.
And typically it's going to be an ID.
- eg. OBJs that you access thru APIs will ea. have an ID
EVENTS
*No need to memorize them (idea for all of them is the same) - look them up on React
DOCs when need to use them
*Most common: onClick, onSubmit, onChange (input change)
*Use camelCase for EVT TYPES - onClick, etc
*Syntax = > <button onClick={handleButtonClick}>click me</button>
(EL’) (EVT) = (HANDLER)
*Typical EVT & HANDLER:

const EventExamples = () => {

// HANDLER
const handleButtonClick = (e) => {

// FORM Attris
alert(e.target.value);
alert(e.target.name);

};
return (
<section>
<button onClick={handleButtonClick}>click me</button>
</section>
);
};

BTN TYPES & EVT TYPES - “SUBMIT”, “BUTTON”


*If:
<button type='submit'>submit form</button> - use onSubmit
<button type='button'>Click me</button> - use onClick

- ELSE: Wont work

EVT HANDLERS - Referenced FN vs Anonymous FN


*Inside EVT L’ - can either have a Reference to a Handler OR an Anonymous FN
*Typically, if the Handler isnt much Code = Anonymous FN, ELSE = Reference

return (
<section>
<button onClick={handleButtonClick}>click me</button>
</section>

return (
<section>
<button onClick={() => console.log('hello there')}>click me</button>
</section>

COMPONENTS ARE INDEPENDENT BY DEFAULT


*In Vanilla JS - you have to jump thru Hoops to eg. Display the Correct FAQ Answer for
a Clicked D-Down - but in REACT, Components are Independent by Default

PROP DRILLING
*Prop drilling is the unofficial term for passing data through several nested children
components
*Can ONLY Pass PROPs = DOWN
*Can become a prob. Bc may have to Pass the Data through many Levels to get it to its
Destination - this is why Alternatives like: “Context API”, Redux & Other State Libraries

INVOKING FNs STRAIGHT AWAY PROBLEM


*Invoke Straight away = “getBook(id)”
*Reference to a FN = “getBook”
*In JS whenever a FN is Referenced w/ Parentheses - eg. “getBook(id)” = Invoked
Immediately but it can cause a Prob when - eg. the Param “id” hasnt been Passed yet -
*he had this Line - but bc of the () the “getBook(id)” FN was being Invoked Straight
away - it was Returning “undefined” bc “id” hadnt been Passed into it yet

<button onClick={getBook(id)}>display title</button>

- bc we NEED the Parentheses to Pass the Param (= “id”) - we need a way to get
Around this prob
- So the 1st SOLUTION was - to Wrap the FN in Another & Pass a Reference to a
FN.
Wrap the “getBook(id)” FN CALL - INSIDE Another FN (that obviously doesnt need
Parentheses (Else = Same Prob again) & Call the Outer FN onClick:

const getSingleBook = () => {


getBook(id);
};

<button onClick={getSingleBook}>display title</button>

The 2nd SOLUTION was - to Wrap the FN CALL Inside an Anon. FN

<button onClick={() => getBook(id)}>display title</button>

ES6 MODULES

*IMPORTS = 2 Main ways: 1. NAMED 2. DEFAULT


*Default - if you are Only Exporting 1 thing (Only 1 Default Export per File)
*Named - if more than 1 thing From a File
- The NAME MUST MATCH (From EXPORT to IMPORT)

*Export/Import a NAMED EXPORT” -

// Export a Named VAR/FN (From “books.js”)


export const books = [...arr vals];

// In “index.js” - Import NAMED Export - thats why we need the {}


import { books } from './books';

*Export/Import a DEFAULT EXPORT” -

// Export a Default VAR/FN (From “books.js”)


export default books

// In “index.js” - Import Default Export - DONT need the {}


import anyName from './books';
IMG FOLDER IN “SRC” FOLDER - (= AUTO-OPTIMISATION BY REACT)
*ALL Assets in SRC DIR = AUTO-OPTIMISED
1. Import ea. IMG into eg. “books.js” (From “src” DIR)
2. Reference ea. IMG - by its VAR NAME

> import img1 from ‘./images/book-1.jpg’;


> img: img1,

BUILD PRODUCTION APP


1. CTRL/C - to Stop Server
2. Npm run build
3. “build” DIR = Created in Project Root DIR (= Production DIR - Dont need “src” now)
4. NETLIFY > Add new site > Deploy Manually (usually we do this thru GITHUB)
> Upload “build” DIR > CLK Link to see Live Site
B. Change Site Name > site settings > Change Site Name

*Sites Addr. = react-course-fundamentals-jq.netlify.app

You might also like