React JS Notes
notes on React JS Library
React JS Overview
added: 12-07-2022, updated: 26-07-2023
What - It is a JS Library, it can be added to HTML page as other JS libraries (like jQuery). It is used to create single-page applications. It uses only one HTML page index.html
and then all changes to page and routes are managed strictly by JS events.
How - You build DOM elements using JS rather than defining them in HTML. To do this easily, use JSX, which is a format that is combination of HTML and JS and it lets write HTML in JS.
Tools Setup:
- Build in Browser using https://react.new/
- Upgrade browser with
React Developer Tool
browser extension. It shows react components.
Quickstart - Traditional Style - Use Without Node.js
You can use react as other JS library by adding script to HTML. Both React and ReactDOM are available over a CDN. Add following to the body of HTML.
This makes React
and ReactDOM
classes available in JS. React.createElement()
function is used to create new DOM elements. ReactDOM.render()
function to render elements in DOM.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React without JSX</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
</head>
<body>
<div id="root"></div>
<script type="text/javascript">
const element = React.createElement(
"h1",
{ className: 'greeting' },
"Welcome User"
);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(element);
</script>
</body>
</html>
Here, a DOM element, element
is defined using React.createElement
which takes createElement(type, props, ...children)
. Type is DOM elem type like p, h2, div. props are properties of type. and then children. It can be multiple children, here we are only passing one child, which is text "Welcome User"
.
Next, we define root
which is used to build rest of DOM tree. Finally, we render root by adding element
to it.
You see how HTML is now written in JS. To make it simple, JSX is introduced which lets write HTML and JS together.
Adding JSX and Babel
Traditionally, HTML is written as string, eg "<h1>"
. Using JSX, you can write HTML in JS.
JSX is not HTML, JSX is JavaScript XML, an extension of JavaScript that allows writing HTML in JS. To execute it, we need a compiler that can convert JSX to JS and HTML, because browsers still expect HTML and JS separately as in traditional way.
Babel is a JS compiler. You can insert plane HTML without quotes. Also add variable names with JS code within curly braces. Eg: <p>Hi {name.toUpperCase()}</p>
.
Babel converts JSX <p>Hi</p>
to JS React.createElement("p", null, "Hi");
on the fly.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React JSX</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone@7.10.3/babel.min.js" crossorigin></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel"> // type is changed from javascript to babel
let msg = "Tom";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<p>Hi {msg}</p>);
</script>
</body>
</html>
Here, first we added babel script to html body. Next, in <script type="text/babel">
type is changed from javascript to babel. This tells comiper to change this before run. Then, in render()
you can see how html and js are written together without using React.createElement()
or HTML with quotes.
JSX and JS go one in another and can be nested using {}
s. When you start JS put in {} , then can again write HTML and again nest JS in {}. Babel can be said it is similar to Jinja in Flask or Blade in Laravel.
Conceptually - Using React, HTML can be written in JS, which renders it and adds it to a HTML DOM element, eg root
. Now that it is in JS, it can be programmed and be data driven and dynamic. To manage the HTML code we split the UI into independent and reusable Components
.
This completes the basic. Now that you have seen how react works and done it all in single html
file, it's time to "raise the bar". In next section you will use node
and create react app. Using single html file is okay for prototype but for production you should use node app. Lets GO....!
Quickstart - with Node.js
Node.js creates structure for react project with Babel, file bundling etc. You can start from scratch as react-starter-pack or use an existing project.
Create new
This, creates a folder, app_name
with all required libraries like react, react dom, babel, react scripts etc.
NPX is a package in node that lets you run and execute packages without having to install them locally or globally. Now do
This will run a web server using node and serve this app on http://localhost:3000
as a dev build.
Use Existing Project
To run an existing react project, that you have downloaded. It would already have package.json
. You need to install all the dependencies locally and that can be done by
It uses package.json
to install all dependencies. Then starts the web-server.
Application Structure
The folder above app_name
, has following files and folders:
package.json
- All dependencies can be seen in this file. Also, inpackage-lock.json
node_modules
dir has all dependencies installed by Node.js.src
is where you code, it has app code. It has all React Magic of JSX.public
dir has what goes to browser, it is used to serve app. It has index.html and other static files.public/manifest.json
- it is not react specific. Modern web standard adds it, it provides information about the app in JSON format. It is used by mobile and desktop when we install this app. We can updateshort_name
andname
here.build
dir will be added later when you create a prod build.
Basics of website is index.html
, it is the same here, public/index.html
. It defines the old giants: html, head, meta tags, title and body. It has <div id="root"></div>
which is picked by react and then your GREAT single-page app is built on top of it! React will build DOMs and render it in this "root" element. This will be "root of your tree" :) .
The react magic starts in src/index.js
, this picks the root div from html and builds the app. This is where you see new things. index.js
is entry point to render app to DOM. public/index.html
has <div id="root"></div>
that is used in index.js
. The render()
function renders the app and takes JSX tree, as argument, that structures the entire app.
What is this new kinda JS code?
Any code that is non-JavaScript standard like "import of file" and "JSX" are converted to standart-JavaScript then they are served on browser. Eg of non-std-js
import varName from 'filename.ext'
// pull any file say image as var
import "./styles.css";
// add css to head
The codes above are from starter-code, they are non-std code and are later compiled and transformed to make it standard JS code and execute on browser.
JSX uses CamelCase while HTML uses lower case.
Third Party Packages
As project proceeds, you can make use of other packages that like UI framework BootStrap.
Here, the it adds two packages:
bootstrap
: UI framework.react-bootstrap
: a React component library wrapper for the bootstrap package.
React Components
You know HTML gives you div/p/h1/span standard components. You use them to build structure of page and add your data to it. This builds your website, right?
Now, using react, you build custom "super-powered" components like:
Imagine, this is your styled header, with all branding and functionality you want and it changes with data you pass.
To define it, react lets you define it as a function that accepts parameters or go OOPs style and define it as a class.
It is that simple...! Isn't it?
This lets split whole page in to independent, dynamic, resuable components. Hence, it is eaisier to manage and control them using JS.
React Component is a building block of app, one of the UI component (same as a template in Flask). Eg, Header
, Sidebar
, Content
and Footer
.
Conceptually components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements (JSX) describing what should appear on the screen. Here is complete code, within src
each component is defined in its own file, eg, app.js
, header.js
.
function Header(props) {
return <h1>Hello, {props.name}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Header name="Sara" />;
export default App
means export this component (function) as default App
component.
So previously we could only render standard tags like <div>
, <p>
etc. but now can render custom tags like <Header />
, also pass properties (props) to it. Remember, every ComponentFunction
follows CamelCase. It should return only one JSX tag like <div>
, <p>
or <Header />
. To return muliple elements, wrap them in div, and if you want to avoid extra divs added to dom, use <React.Fragment>blah blah</React.Fragment>
or shorthand <> ...
.
Props make components dynamic. You can use logic in any component, like hiding sidebar when loggin in. Props is basically an JSON object
(key-value), its properties can passed in JSX in same way as we pass props in HTML <App name="Tom" yob={1990}>
, they are passed where we render a component. It can be recieved as function App(props)
or as using ES6 as function App ({name, yob})
.
A component must return a representation of itself as an HTML element tree.
Javascript tricks to use in React
To loop lists of elements use map()
of Array
class. You can map a function to an array, that is, apply a functions to each element of array and return the applied value for each of them.
The above returns three <li>
elements.
React required 'key' for every dom element so that it can maintain their state.
and include a key
attribute with a unique value per element. React requires it to efficiently rerender only part of list.
eg, <p key={data.id}></p>
Conditional Logic: you may need to apply if-then or if-then-else when returning DOMs. Eg, if there are post then return post else return 'User has no posts.'. This can be implemented in React using &&
(if-then) and ?:
(if-then-else) operators. Expression on right of && is executed when left is true. Eg,
function Posts() {
const posts = [
{id: 1, text: 'Hello, world!'},
{id: 2, text: 'The Next Post'},
];
return (
<>
{posts.length === 0 ?
<p>There are no blog posts.</p>
:
posts.map(p => {
return (
<p key={post.id}>{post.text}</p>
);
})
}
</>
);
}
Ways to handle conditional in JSX, JSX Conditional Expressions
Good strategy is to build multiple components with each having one purpose. Eg, Header
Sidebar
. Add ContentArea
that can be swapped based on navigation.
Components can be nested to build hierarchy. Eg,
If the component is called with children, like above, then a children
key is included in props
object, which is equal to child components, here <Posts />
.
Class Implementation
Component can also be a ES6 Class, that extends React.Component
and implements render() {}
.
React-Bootstrap
React-Bootstrap provides Container
and Stack
components to design layout of website.
return (
<Container fluid className="App"> // className is HTML class
... // <-- no changes to JSX content
</Container>
);
Strategy of components
- build base components like
header
,content
footer
. - use them in pages.
Hooks
useState Hook
useState is a function in React class that can be used to manage state of App.
useState(arg)
arg can be any data type.
it returns array having [stateValue, setStateFunc] = setState("a Value")
we can use them in app to manage states. We can have multiple states of app, so make multiple instance of this function.
Whatever is the variable, the setter works for it, don't think of how this function is defined.
useEffect Hook
These are like eventListners that can listen to some variable and if there is a change in its state they can do something.
useEffect(funcDoSomething, [varToListenTo]);
when arg2 changes, arg1 is executed. arg2 = [] then only run once, arg2 can have multiple vars to listen to.
useReducer Hook can be used to manage state and effect at once.
It takes two arguments, arg1 is function to execute on state change, and arg2 is initial state value.
It returns, 1 state value, 2 function to change state. Eg, state is counterValue
ToDo: Need some more understanding here on, how to use reducer to do different action based on param passed?
Handling Forms
added: 14-07-2022, updated: 26-07-2023
Uncontrolled Component: useRef
we can create instance of this function and attach that to form inputs.
const empName = useRef();
<input ref={empName} ...>
// on Submit
a = empName.current.value; // GET
empName.current.value = 'A'; // SET
We can get and set the values using empName.current.value
Controlled Component: useState
and bind to input tag using onChange
:
const [empName, setEmpName] = useState("");
<input value={empName} onChange={ (e) => setEmpName(e.target.value) } ...>
// on Submit
a = empName; // GET
setEmpName("A"); // SET
Custom Hooks
We can create our own custom hooks that can be reused based on our requirements. They have to start with use...
. They instantiate another hook within them. Eg, we can make a custom hook to handle form events like setting default value, getting current value, onChange events, validation etc.
Others: formik.org, react-hook-form.com, usehooks.com
Routes
React makes SPA, only one page is served from server. So react-router-dom
is library that can be used to manage routes on browser.
In index.js
orApp.js
you can create <Route>
in <Routes>
having path
and element
.
import { App, About, Contact } from "./App";
import { BrowserRouter, Routes, Route, Navigate } from react-router-dom";
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</BrowserRouter>,
document.getElementById("root")
);
You can link routes to create hierarcy. Use { Link }
a XHR, to add link to component in DOM. It is like url_for
in Flask.
Routes with Bootstrap
Bootstrap has Nav.Link
component that creates nav-item, it has as
and to
props to work with React-Route's NavLink
.
import Navbar from "react-bootstrap/Navbar";
import Nav from "react-bootstrap/Nav";
import { NavLink } from 'react-router-dom';
export default function Sidebar() {
return (
<Navbar sticky="top" className="flex-column Sidebar">
<Nav.Item>
<Nav.Link as={NavLink} to="/">Feed</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={NavLink} to="/explore">Explore</Nav.Link>
</Nav.Item>
</Navbar>
);
}
Parameters and Routes
To define a route with a dynamic section, the path attribute of the Route component uses a special syntax with a colon prefix:
The component referenced by the element attribute or any of its children can use the useParams()
hook function to access the dynamic parameters of the current URL as an object.
Development and Structuring
Following steps can help you build a React App:
- Plan the UI that you want to build as a wireframe or sketch.
- Break the UI into top level Components like header, sidebar, content and footer.
- Build these components and place in
src/components
- Build these components and place in
- Think of logical pages that use the above components but have different low level componenets. Eg, ProfilePage and FeedPage, both have header, sidebar and content BUT the content will have different sub-components like profile or posts.
- Build these components and place in
src/pages
- Build these components and place in
- Build routes for these Pages and update the header.
State - use to set and get data, like responses, session variables and state (loading, error, done)
Effect - use to do functionality like - fetch, or any function.
If a function returns JSX then it is a react component.
Testing
Jest.js
is used to write test.
Deployment
App can be deployed to Netlify.com
Do npm run build
and then build
folder has prod ready code to deploy.
React Way
- there is a JSX tree which has components
- components are mostly UI blocks, or transparent utility like Routes, Context.
Props
are variables that you can send to component to make them dynamic or reusable.- url parameters are managed in
useParam
hook - data is managed by
useState
- any work like, backend call, update state, re-render component is done using
useEffect
. It has dependencies, which can be param or prop.. so - URL param and prop can trigger effect, effect can do calls and set state which re-renders. This is URL param, to trigger effect, to re-render, thus things get dynamic in react-way.
- if anything in useEffect arg2-dependency-var changes, it executes arg1-function which sets state var, which rerenders components.
- Eg, in code below, as soon as username changes in url, it updates
username
which is dependency vriable inuseEffect
so it runs async, which fetches new user and then sets user, which is re-rendered in component. - The better your backend is structured, models, rest, pagination etc. the better it is to use react and bootstrap. So base has to be structured.
- Never render contents directly to the page with DOM APIs, as this introduces a risk of XSS attacks.
// url: /users/:username
const { username } = useParams();
const [user, setUser] = useState();
const api = useApi();
useEffect(() => {
(async () => {
const response = await api.get('/users/' + username);
setUser(response.ok ? response.body : null);
})();
}, [username, api]);
return (
<p>user.name</p>
);
Extras
Notice here, that it is not only JS packages but also CSS frameworks like bootstrap
. CSS are loaded to HTML using JS line
// Load only css file
import 'bootstrap/dist/css/bootstrap.min.css';
// Alternatively, load entire library
import Container from 'react-bootstrap/Container'
Resources
Links
- React Tutorial Miguel Grinberg - https://blog.miguelgrinberg.com/post/the-react-mega-tutorial-chapter-2-hello-react
- LinkedIn Learning - https://www.linkedin.com/learning/react-js-essential-training
- React Docs - https://reactjs.org/docs/hello-world.html
- ECMA 6+
Next
- ReactNative
- GraphQL