0% found this document useful (0 votes)
9 views

React Research

The document provides an overview of core React concepts including elements and JSX, components and props, lists and keys, and events and event handlers. It then covers React hooks including useState, useEffect, useCallback, useMemo, and useRef. Finally it discusses advanced hooks like useContext, useReducer, writing custom hooks, and rules of hooks.

Uploaded by

mangelique9880
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

React Research

The document provides an overview of core React concepts including elements and JSX, components and props, lists and keys, and events and event handlers. It then covers React hooks including useState, useEffect, useCallback, useMemo, and useRef. Finally it discusses advanced hooks like useContext, useReducer, writing custom hooks, and rules of hooks.

Uploaded by

mangelique9880
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

React

React

Core Concepts
● Elements and JSX
● Components and Props
● Lists and Keys
● Events and Event Handlers

React Hooks
● State and useState
● Side Effects and useEffects
● Performance and useCallback
● Memoization and useMemo
● Refs and useRefs

Advanced Hooks
● Context and useContext
● Reducers and useReducer
● Writing custom hooks
● Rules of hooks

Core Concepts

Elements and JSX


● The basic syntax for a React element

// In a nutshell, JSX allows us to write HTML in our JS


// JSX can use any valid HTML tags
<div> Hello React </div>
● JSX elements are expressions

// as an expression, JSX can be assigned to variables . . .


const greeting = <div> Hello react </div>

const isNewToReact = true;

// . . . or can be displayed conditionally


function sayGreeting( ) {
if (isNewToReact) {
// . . . or returned from functions, etc.
} else {
Return <div> Hi again, React </div>
}
}

● JSX allows us to nest expressions

const year = 2020;


// we can insert primitive JS values in curly braces: { }
const greeting = <div> Hello React in {year} </div>;
// trying to insert objects will result to an error

● JSX allows us to nest elements

// to write JSX on multiple lines, wrap in parentheses: ( )


const greeting = (
// div is the parent element
<div>
{ /* h1 and p are child elements */}
<h1>Hello!</h1>
<p>Welcome to React</p>
);
/* 'parents' and 'children' are how we describe JSX elements in
relation to another
like we would talk about HTML elements */
● HTML and JSX have a slightly different syntax

// Empty div is not <div></div>, (HTML), but </div> (JSX) <div/>

// A single tag element like input is not <input> (HTML), but


<input/> (JSX) <input name="email" />

// Attributes are written in camelcase for JSX (like JS variables


<button className="submit-button">Submit</button> )
// not 'class' (HTML)

● The most basic React app requires three things:


○ ReactDOM.render( ) to render our app
○ A JSX element (called a root node in this context)
○ A DOM element within which to mount the app (usually a div with an id of root
in an index.html file)

// imports needed if using NPM package; not if from CDN links


import React from "react";
import ReactDOM from "react-dom"l

const greeting = <h1> Hello React </h1>

// ReactDOM.render (root node, mounting point)


ReactDOM.render(greeting, document.getElementById("root));
Components and Props

● The syntax for basic React component


import React from "react";

// 1st component type: function component


function Header() {
// function components must be capitalized unlike normal JS
functions
// note the capitalized name here: 'Header'
Return <h1>Hello React </h1>;
}

// function components with arrow functions are also valid


const Header = () => <h1>Hello React</h1>;

// 2nd component type: class component


// (classes are another type of function)
class Header extends React.Component {
// class components have more boilerplate (with extends and
render method)
render() {
return <h1>Hello React</h1>;
}
}
● How components are used

// do we call these function components like normal functions? N.O

// to execute them and display the JSX they return . . .


const Header = () => <h1>Hello React</h1>;

// . . .we use them as 'custom' JSX elements


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

● Components can be reused across our app


// for example, this Header component can be reused in any app page

// this component shown for the '/' route


function IndexPage() {
return (
<>
<Header />
<Hero />
<Footer />
</>
);
}

// shown for the '/about' route


function AboutPage() {
return (
<>
<Header />
<About />
<Testimonials />
<Footer />
</>
);
}
● Data can be dynamically passed to components with props
// what if we want to pass data to our component from a parent?
// to pass a user's name to display in our Header?

const username = "John";

// we can add custom 'attributes' called props


ReactDOM.reder (
<Header username={username} />,
document.getElementById("root")
);

// we called this prop 'username', but can use any valid JS


identifier

// props is the object that every component receives as an argument


function Header(props) {
// the props we make on the component (in this case the
'username')
// become properties on the props object
Return <h1>Hello {props.username}</h1>;
}

● Props must never be directly changed or mutated


// components must ideally be 'pure' (non-mutated) functions
// for every input, will be the same exact output

// we cannot do the following with props:


function Header(props) {
// we cannot mutate the props object, we can only read from it
props.username = "John.Doe";

return <h1>Hello {props.username}</h1>;


}
// we can use a useState (use state) to modify a prop value
● Children props are useful if we want to pass elements and/or components as props to
other components
// we can accept React elements or components as props through a
'children' property

function Layout(props) {
Return <div className="container">{props.children}</div>;
}

// the children props are very useful if we want the same component
to wrap all other components:
function IndexPage() {
return (
<Layout>
<Header />
<Hero />
<Footer />
</Layout>
);
}

// different page, but uses the same Layout component (the result of
using children prop)
function AboutPage() {
return (
<Layout>
<About />
<Footer />
</Layout>
);
}

● Conditionally displaying components with ternaries and short-circuiting

// if-statements are valid to conditionally show, but only ternaries

allows us to insert these conditionals is JSX

function Header() {

const isAuthenticated = checkAuth();

return (

<nav>

<Logo />

{/* if isAuth is true, show AuthLinks. If false,

Login */}

{isAuthenticated ? <AuthLinks /> : <Login />}

{/* if isAuth is true, show Greeting. If false, nothing. */}

{isAuthenticated && <Greeting />}

</nav>

);

}
● Fragments are special components for displaying multiple components without adding an
extra element to the DOM
○ Fragments are ideal for conditional logic

// if isAuthenticated is true, this is how we apply AuthLinks and


Greeting:
function Header() {
const isAuthenticated = checkAuth();

return (
<nav>
<Logo />
{/* we can render both components with a fragment
*/}
{/* fragments are concise: <> </> */}
{isAuthenticated? (
<>
<AuthLinks />
<Greeting />
</>
) : (
<Login />
)}
</nav>
);
}
Lists and Keys

● Use .map() to convert lists of data (arrays) into lists of elements

const people = ["John", "Bob", "Fred"];


const peopleList = people.map((person) => <p>{person}</>);

● .map() is also used for components as well as elements

function App() {
const people = ["John", "Bob", "Fred"];
// can interpolate returned list of elements in {}
return (
<ul>
{/* we're passing each array element as props */}
{people.map((person) => (
<Person name ={person}
))}
</ul>
);
}

function Person({ name }) {


// gets 'name' prop using object destructuring
return <p>this person's name is: {name}</p>;
}

● Each React element iterated over needs a special ‘key’ prop


○ Keys are essential for React to be able to keep track of each element that is being
iterated over with map
○ Without keys, it is harder for it to figure out how elements should be updated
when data changes
○ Keys should be unique values to represent the fact that these elements are separate
from one another
function App() {
const people = ["John", "Bob", "Fred"];

return (
<ul>
{/* keys need to be primitive values, ideally a
generated id */}
{people.map((person) => (
<Person key={person} name={person} />
))}
</ul>
);
}

// if you don't have ids with your set of data or unique primitive
values,
// you can use the second parameter of .map() to get each element
index
function App() {
const people = ["John", "Bob", "Fred"];

return (
<ul>
{/* use array element index for key */}
{people.map((person, i) => (
<Person key{i} name{person} />
))}
</ul>
);
}
Events and Event Handlers

● Events in React and HTML are slightly different

// **most event handler functions start with 'handle'

function handleToggleTheme() {

// code to toggle app theme

// in HTML, onclick is all lowercase

<button onclick="handleToggleTheme()">

Submit

</button>

// in JSX, onClick is camelcase

// also used in passing references to the function with curly braces

{}

<button onClick={handleToggleTheme}>

Submit

</button>

● The most essential React events to know are onCLick and onChange
○ onClick handles click events on JSX elements (buttons)
○ onChange handles keyboard events (inputs)
function App() {

function handleChange(event) {

// when passing the function to an event handler, like

onChange

// we get access to data about the event (an object_

const inputText = event.target.value;

const inputName = event.target.value; // myInput

// we get the text typed in and other data from

event.target

function handleSubmit() {

// onClick doesn't usually need event data

return (

<div>

<input type="text" name="myInput"

onChange={handleChange} />

<button onClick={handleChange>Submit</button>

</div>

);
}

React Hooks
State and useState

● useState gives us local state in a function component

import React from "react";


// create state variable
// syntax: const [stateVariable] = React.useState(defaultValue);
function App() {
const [language] = React.useState("javascript");
// we use array destructuring to declare state variable

return <div>I am learning {language}</div>


}

● Note: Any hook in this section from the React package and can be imported individually

import React, { useState } from "react";

function App() {
const [language] = useState("javascript");

Return <div>I am learning {language}</div>


}
● useState also gives us a ‘setter’ function to update the state it creates

function App() {

// the setter function is always the second destructured value

const [language, setLanguage] = React.useState("python");

// the convention for the setter name is 'setStateVariable'

return (

<div>

{/* why use an arrow function here instead

onClick={setterFn()} ? */}

<button onClick={() => setLanguage("javascript")}>

Change language to JS

</button>

{/* if not, setLanguage would be called immediately

and not on click */}

<p>I am now learning {language}</p>

</div>

);

/* note that whenever the setter function is called, the state


update,

and not the App component re-renders to display the new state */

● useState can be used one or multiple times within a single component

function App() {

const [language, setLanguage] = React.useState("python");

const [yearsExperience, setYearExperience] = React.useState(0);

return (

<div>

<button onClick={() => setLanguage("javascript")}>

Change language to JS

</button>

<input

type="number"

value={yearsExperience}

onChange={(event) =>

setYearExperience(event.target.value)}

/>
<p>I am now learning{language}</p>

<p>I have {yearsExperience} years of experience</p>

</div>

);

● useState can accept primitive or object values to manage state

/* we have the option to organize state using is the most appropriate


data type, according to the data we're tracking */
function App() {
const [developer, setDeveloper] React.useState({
language: "",
yearsExperience: 0,
});

function handleChangeYearsExperience(event) {
const years = event.target.value;
// we need to pass in the previous state object with the spread
operator
setDeveloper({ ... developer, yearsExperience: years });
}

return (
<div>
{/* no need to get previous state here,
we are replacing the entire object */}
<button
onClick={() =>
setDeveloper({
language: "javascript",
yearsExperience: 0;
})
}
>
Change language to JS
</button>
{/* we can also pass a reference to the function */}
<input
type="number"
value={developer.yearExperience}
onChange={handleChangeYearsExperience}
/>
<p>I am now learning {developer.language}</p>
<p> I have {developer.yearsExperience} years of experience</p>
</div>
);

● If the new state depends on the previous state, to guarantee the update is done reliably, we
can use a function within the setter function that gives us the correct previous state

function App() {
const [developer, setDeveloper] = React.useState({
language: "".
yearsExperience: 0;
isEmployed: false,
});

function handleToggleEmployment(event) {
// we get the previous state variable's value in the
parameters
// we can name our 'prevState' however we like
setDeveloper((prevState) => {
return { ...prevState, isEmployed:
!prevState.isEmployed };
// it is essential to return the new state from this
function
});
}
return (
<button onClick={handleToggleEmployment}>Toggle Employment
Status</button>
);
}

State and useState

● useEffect lets us perform side effects in function components.


Side Effects
○ Where we need to reach into the ‘outside world’. For example, fetching data from
an API or working with the DOM
○ Actions that can change our component state in an unpredictable fashion (that
have caused ‘side effects’).
● useEffect accepts callback functions (‘effect’ function), which runs by default every
time there is a re-render
● useEffect runs when our components mounts, which is the right time to perform s side
effect in the component lifecycle

// Pick a color from the colors array and make it the background
color
function App() {
const [colorIndex, setColorIndex] React.useState(0);
const colors = ["blue", "green", "red", "orange"];

// performing a 'side effect' since we're working with an API


// working with the DOM, a browser API outside of React
useEffect(() => {
document.body.style.backgroundColor = colors[colorIndex];
});
// whenever state is update, the app re-renders and useEffect runs

function handle ChangeIndex() {


const next = colorIndex + 1 === colors.length ? 0 : colorIndex + 1;
setColorIndex(next);
}

return <button onClick={handleChangeIndex}>Change background color


</button>;
}

You might also like