Basics
React is a JavaScript library to build user interfaces. React allows us to build the structure for our website.
With React it is really common to build single page applications. We have one site with one single template and update the components in the DOM that get shown.
Components
Components are the building blocks of our application. Allow us to make the visual layer of our application. They let us split up our UI in individual reusable pieces. Each part of the UI gets build up as a seperate component and then get added to the parent component.
A component is a JS class or function that returns JSX, which is similar to html code.
Components can be nested as deep as you want.function Tweets(){
return(
<div>
<Tweet/>
</div>
)
}
function Tweet(){
return (
<div>
<Author/>
<Content/>
<Actions/>
</div>
)
}
JSX
Javascript XML looks like HTML with some slight syntax differences and gives us some added functionality. You write it in a camelCase
style.
The advantage of using React over HTML is that you can use dynamic JavaScript values in your JSX.
function Profile({name}){
return(
<div className="profile-container">
<h1>Hello, my name is {name}</h1>
<button onClick={alert('hello')}></button>
</div>
)
}
{name}
to pass JS variables and logic directly into the html.
This makes our attributes dynamic depending on the variables in the brackets.
//dynamic attributes
const src = "/react.svg"
<img src={src}/>
//dynamic styles with a JS object inside the {{}}
const background = 'red'
<div style={{background}}/>
JSX tags are similar to HTML tages.
Differences:
- class declaration: className=
instead of class=
- how events get handled.
Browser actually can't read JSX so the code gets run through a compiler and gets converted into HTML and JS once it is shown in the browser.
Fragments
JS functions can only return one thing. In React you can only return one parent element from a component.
For example you CAN'T do this without getting the error JSX expressions must have one parent element
.
function App(){
return(
<Header/>
<Main/>
)
}
//We could fix this by wrapping a component in a div
function App(){
return(
<div>
<Header/>
<Main/>
</div>
)
}
//To not add another element to your page you can use an emty component called Fragment
<>
<Header/>
<Main/>
</>
Rendering
The way how and when to render our App React uses the VirtualDOM or VDOM.
The React rendering steps are: - Has the state of our React app changed? If Yes -> React updates the VDOM - React uses 'diffing' process to compare the updated VDOM with a previous version to see what changed. - Once it sees what is different React uses a process called 'Reconciliation' to update the real DOM with the updated changes.
Event Handling
Handling the user interactions. Event handling is how we take the user events and do something with them.
React has build-in events like:
- onClick
- <button> onClick={handleClick}/>
- onChange
- <input> onChange={handleChange}/>
- onSubmit
- <form> onSubmit={handleSubmit}/>
Alert user when button clicked
We would add the onClick
event to the button and refer a function that shows the alert.
function redAlert(){
const handleClick= ()=> {
alert('RED')
}
return (
<button onClick={handleClick}>Click me</button>
)
}
React Router
Using React Router we can have multiple pages in a singel page application. We handle URL routing with a Router
that keeps our UI insync with our URL.
import{BrowserRouter as Router, Route} from 'react-router-dom'
function App(){
return (
<div className="App">
<Router>
<Route path='/' element = {<Home/>}/>
<Route path='/profile' element = {<Profile/>}/>
<Route path='/product' element = {<Product/>}/>
</Router>
</div>
);
}
Props
When you need to pass data down from one compenent to another you can pass it down as a prop.
A prop can be passed down like a function parameter.
To make a prop create a name on the component you want to pass data to and set it equal to some value.
<Greeting text={'HI'}/>
You then can use that prop inside the component you past it too.
props
refers to properties of an object.
function Tweet(){
let item = {
'author':'Dennis',
'tweet':'My first tweet'
}
return (
<div>
<Author/>
<Content body={item.tweet}/>
<Actions/>
</div>
)
}
function Content(props){
return(
<p>{props.body}</p>
)
}

You can pass anything as a prop even other components. The passed components are called children. You can access them with the props.children
<Parent/>
to
<Parent>
<Child/>
</Parent>
function Parent(props){
return <div>{props.children}</div>
}
Manage Data in app with State
State
is like a snapshop from a camera - like a screenshot of our app at any given time. State
is a JS object used to represent information in or about a component.
To manage state we can't use JS variables because they don't cause our App to re-render.
useState
takes an argument that serves as a starting value of the state variable and returns and array which contains the state variable and a function to update that state.
const [likes, setLikes] = useState(0)
function Likes(){
const [likes,setLikes] = useState(0)
const handleClick = () => {
setClicks(likes+1)
}
return(
<button onClick={handleClick}>Likes{likes}!
</button>
)
}
useState(starting value)
to create a component state.
For example a list of notes that we want to render in our app.
function Notes(){
let [notes,setNotes] = useState([])
return(
<ul>
{notes.map(note=> (
<li>{note.title}</li>
))}
</ul>
)
}
Update State
Set State as empty array then we request some data from our api and update that state with new data.
let [notes,setNotes] = useState([])
let getNotes = async () => {
let response = await fetch('/notes')
let data = await response.json()
setNotes(data)
}
Controlled components
Controlled components use States to have more predictable behaviour.
function ControlledInput(){
const [value,setValue] = useState('')
return(
<input
value={value}
onChange={(e)=>setValue(e.target.value)}
/>
)
}
setValue
puts what is tiped into State.
- The state value
is updated
- Input uses the updated state as its value
Great pattern to use because we want to change the components behaviour we just need to change the state that controls it.
The state update will trigger component lifecycle effect.
Component Lifecycle
A component in React has lifecycle that it goes through. Three main phases: - Mounting Phase - When it gets added to the DOM - Updating Phase - When we are modifying something and that component needs to update. - Unmoting Phase - When this component gets removed from the DOM.
Class components
Methods to take care of Phases
componentDidMount(){
//Component mounted
}
componentDidUpdate(){
//Finished component updating
}
componentWillUnmount(){
//Component is being removed from DOM
}
Functional components
useEffect()
method allows us to handle each of the components lifecycle
Hooks
React Hooks allow us to hook into features such as useState
within function components.
Only apply to functional components.
Hooks led us add State and other features without using class based components.
Before Hooks functional components couldn't hold states.
Hooks are functions that allow us to hook into and manage States.
State hooks
Help you manage state within react components.
useState()
- Set & update states
useReducer()
Context Hooks
Let you use data passed through React Context
useContext()
Ref Hooks
Let's you reference things like HTML elements
useRef()
Effect Hooks
Let's you connect with external systems like browser apis
useEffect()
- Perform side effects in lifecycle
Performance Hooks
Improve performance by preventing unnecessary work.
useMemo()
useCallback()
Purity
Pure react components mean that the same input should always return the same output. To keep a component pure they should only return JSX and Don't change objects or variables that existed before rendering.
The Cup
component is impure because it changes the variable inside of render. Which exists outside the component. This leads the JSX to have the wrong output when the component is used multiple times.
<App/>
component.
Execute something outside our ReactApp
Talk to browser API or make a request to server we use Effects. It is code that reaches outside of our React app. Usually effects also called side effects can be done in event handlers. For example make a HTTP Request when user submits a form.
If you can't run your side effect in a event handler you can useuseEffect()
hook.
For example fetch data when a component first loads.
Refs
To step outside of React and work directly with the DOM. To reference an actual DOM element you can use what is called ref
.
You can create a ref
with the useRef()
hook and to get access to a DOM element use the ref
prop on any React element.
ref.current.focus()
Context
A way to pass prop data through apps components. Most of React Apps have a lot of nested components. To not need to pass props through every child component, that not even need the data, just to get the data in the n-th child we can use Context
. It lets us jump to where the data is needed without making props.
To use Context
- 1. Create context in parent component: const AppContext = createContext()
- 2. Wrap component in special component called .Provider
:
<AppContext.Provider value="Hola">
- 4. Access data within any child component with the useContext()
hook.
Portals
Are like Context but for components. They let you move React components into any HTML element that you select. They are great for components that can't be displayed properly because of their parents components styles. For example for displaying modals, dropdowns and tooltips.
To create a portal use createPortal()
function, pass the component to it, and choose the html element where you like your React component to appear.
<div>
<p> I'm in the parent div.</p>
{createPortal(
<p> I'm in the document body</p>,
document.body
)}
</div>
Suspense
Special component that helps you loading a component or its data. Here show loading component while loading the component.
Suspense
is helpful for components that need some time to fetch data.
Provides a better user experience.
It is also usefull if you lazily load a component. Lazily loading lets us load a component only when it is needed.
//For lazy-loading component
const Component = lazy(
()=>import('./Component')
)
<Suspense fallback={<Loading/>}>
<Component>
</Suspense>
Error Boundaries
Error boundaries let you catch app-breaking errors and show a fallback component to tell the user what happened.
import {ErrorBoundary} from 'react-error-boundary'
function Fallback({error}){
return(
<div role="alert">
<p> No user provided:</p>
<pre>{error.message}</pre>
</div>
);
}
<ErrorBoundary FallbackComponent={Fallback}>
<App/>
</ErrorBoundary>
State Managment
It makes sense to have Component Sate for the single component and Global State to manage multiple components.
We can use the build in Context API or a third party package like Redux.
Virtual DOM
React creates a virtual DOM which is a virtual representation of the real DOM. When we are updating our components we actually updating the virutal DOM not the real DOM. This enables that React can figure out the most performant way to update only the elements that changed instead of updating the whole DOM.
KeyProp
Key is a unique number or string to identify a component. Each item in a dynamically rendered list needs a key prop or you get an error `Warning: Each child in an array or iterator should havd a unique "key" prop.
If you don't have a unique value you can use the current index inside the map function.Event Listeners
Handling Events in React is similar to handle events in traditional JS with some differences.
<li onClick={openNote}>
There is no need for methods like addEventListener('click',openNote)
Forms
Handling forms in React is differnt from the HTML way, because we want to hold our information in a State inside our component.
HTML elements like <input>,<select>
normally maintain and update there state based on the user input.
With react we add event listeners to each field and update our component state whenever one of these imputs change.
OnChange
or submit
would directly update our state and controlled by our own function handleSubmit
instead of letting the form handle it on its own.
<form onSubmit={handleSubmit}>
<input type="text" onChange={updateNoteValue} value={note}/>
<input type="submit">
</form>
Conditional Rendering
When you want to render components depending of the state of other values inside your app.
For example if user logged in show different icon than when user not logged in
.
A way to handling this are Logical && Operator.
or the inline if else conditional operator for some extra logic.return(
<div>
{userIsLoggedIn ? (
<span> Hi {user.name}</span>
):(
<span> Please Login></span>
)}
</div>
)
Commands
Create React app
npx create-react-app <appName>
Start development server
npm start
Create optimized build of app
npm run build
Source
The information are from: Dennis Ivy Youtube