- React
- Contents
- overview of react
- overview of this repository
- react as single files
- Terms
- Introduction And Getting Started
- JSX
- Rendering
- Components
- React Router
- Elements
- projects
- API
- API Google Calendar
- API Google Maps
- Lifecycle
- React Native
- React Hooks
- React With JWT
- next js
- references
- installation
- chapter 2 - add css
- chapter 3 - fonts and images
- chapter 4 - layouts and pages
- chapter 5 - navigation
- chapter 6 - database
- rendering
- streaming
- upgrading react canary libraries to latest version
- next js dashboard 02 css
- next js dashboard 03 images
- next js dashboard 04 routing
- next js dashboard 05 database
- next js dashboard 06
- testing
- components
react is a javascript framework by react which has grown to be hugely popular and arguably the most widely used javascript framework in use today.
the goal of this repository is to aid in my own learning journey of react
the respository is several years old (2018) so some of the code will need refactoring before it runs
some code has been updated (october 2024)
visit single-files to get some starter examples of react as a single file
visit [projects] for a more comprehensive look at various projects, often with several versions as they increase in complexity
for example to get started you can try
- hello-world for starer projects
- components for the use of simple components
- router for a starter project as a multi-page app
and all these projects have been updated as of october 2024
with some older projects not yet updated we have
- api various projects reading various api eg google maps
- react with bulma css demo app with bulma css built into the react app
- mern full stack shopping app full stack react app with mongo db
- next js taster app first foray into next js just getting used to the terminology and layout
- to do of course you have to build a to do app !!! Here is is !!!
- state looking at react state
- HOC Higher Order Component
- Render props - used to share state between components
- reducer - function which determines changes to state.
- reducer - pure function, takes previous state and action and returns next state
- Redux - manages state changes
** note - some of these notes may be out of date as they were originally written in 2018**
Introduction And Getting Started
We can read about JSX in detail here
https://reactjs.org/docs/jsx-in-depth.html#html-tags-vs.-react-components
finding react has made some breaking changes
so reinstalled the framework from scratch
pnpm create react-app component-01a && cd component-01a && rm -rf package-lock.json && rm -rf node_modules && pnpm install && pnpm startand modified index.js to suit
just rendering one component
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
class DisplayThis extends React.Component {
render() {
return <div>
<h1>Component ... name ... {this.props.name}</h1>
</div>
}
}
root.render(
<React.StrictMode>
<DisplayThis name="Component01" />
</React.StrictMode>
);rendering multiple components
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
class Component01 extends React.Component {
render() {
return <h3>This is a component displaying here {this.props.name}</h3>
}
}
class Component02 extends React.Component {
render() {
return <h3>This is a component displaying here {this.props.name}</h3>
}
}
class Component03 extends React.Component {
render() {
return <h3>This is a component displaying here {this.props.name}</h3>
}
}
class DisplayThis extends React.Component {
render() {
return <div>
<h3>Component ... name ... {this.props.name}</h3>
</div>
}
}
const element =
<>
<Component01 name="Component01" />
<Component02 name="Component02" />
<Component03 name="Component03" />
<DisplayThis name="DisplayThis" />
</>;
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{element}
</React.StrictMode>
);this creates a component as a separate file
cloning from component 02 as the start point (not cloning the libraries)
install libraries and run with
pnpm install && pnpm startApp.js which imports App2 component also
import './App.css';
import Child from './Child';
function App() {
return (
<div className="App">
Parent Component
<Child />
<Child />
<Child />
<Child />
<Child />
</div>
);
}
export default App;and the child component
function Child() {
return (
<div className="App2">
Subcomponent
</div>
);
}
export default Child;renders as
This shows passing data down from one component into another
We pass name data down from root index to component App
to get started we copy code apart from node_modules and pnpm-lock.yaml from previous project, then run
pnpm install && pnpm startindex.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App name="root element"/>
</React.StrictMode>
);we refer to the component and pass data in
import ComponentFixed from "./ComponentFixed";
import ComponentWithData from "./ComponentWithData";
function App(data) {
return (
<div className="App">
<h1>{data.name}</h1>
<ComponentFixed />
<ComponentWithData data={{ name: "Component with data" }} />
</div>
);
}
export default App;and just render out the data
function ComponentWithData({data}) {
return(
<>
{data.name}
</>
);
}
export default ComponentWithDataoutput is
We can write a component as a class rather than as a function
import ComponentFixed from "./ComponentFixed";
import ComponentWithData from "./ComponentWithData";
import ComponentAsClass from "./components/ComponentAsClass";
import ComponentAsFunction from "./components/ComponentAsFunction";
function App(data) {
return (
<div className="App">
<h1>{data.name}</h1>
<ComponentFixed />
<ComponentWithData data={{ name: "Component with data" }} />
<ComponentAsFunction data={{ name: "Component A As Function" }} />
<ComponentAsClass data={{ name: "Component B As Class" }} />
</div>
);
}
export default App;and the component
import React from 'react'
class ComponentAsClass extends React.Component {
render() {
return <div>
<p>This is component as a class<br />props are '{this.props.data.name}'</p>
</div>
}
}
export default ComponentAsClasswhich looks like
original router-01 was no longer working so I built a fresh version
npx create-react-app router-01
cd router-01
npm install
npm startthe app compiles and runs fine
add in router
control-C to stop the app running
npm install --save react-router-domjust out of curiosity i am going to try to build the same thing with pnpm to see what happens
copy the whole app apart from node-modules folder
pnpm install
pnpm startseems to work fine
let's try building from scratch using pnpm to see if it all works fine
npx create-react-app router-03
cd router-03
rm package-lock.json
pnpm install
pnpm start
Control-C let's see if we can automate this in one command
npx create-react-app router-04 && cd router-04 && rm -rf package-lock.json rm -rf node_modules && pnpm install && pnpm startseems to work fine
it's working but there does not seem to be much or any disk space improvement which is weird ... we are looking at 200MB to 300MB of node module libraries which is just insanely huge and this is repeated every time
let me try another approach
i am going to try to use pnpm to install from scratch
someone else did try it here
https://dev.to/lico/set-up-create-react-app-using-pnpm-nji
so let's give it a go
pnpm create react-app router-05 && cd router-05
rm -rf package-lock.json && rm -rf node_modules
pnpm install && pnpm start
pnpm create react-app router-02 && cd router-02 && rm -rf package-lock.json && rm -rf node_modules && pnpm install && pnpm start
pnpm create react-app router-05 && cd router-05 && rm -rf package-lock.json && rm -rf node_modules && pnpm install && pnpm startbut the folder size is the same
cd router-01 && du -s && cd .. && cd router-02 && du -s && cd .. && cd router-03 && du -s && cd .. && cd router-04 && du -s && cd .. && cd router-05 && du -s && cd ..so not sure the benefits of pnpm in this instance ... puzzling ...
This app follows this tutorial on YouTube https://www.youtube.com/watch?v=unr4s3jd9qA
This is a series of apps built from Traversy Media and his, Brad Traversy, amazing walkthroughs on teaching coding in a very simple fashion, line by line, which I like.
This app builds a back end MongoDB, a back end API to expose the DB, database containing shopping items and users, creation of tokens on user registration, validation of token on user login. Also it creates a React front end application which lists shopping items and has a user registration, login and logout page. Shopping items can be listed without authentication but not added nor removed unless authentication has taken place.
Creating an starter template in React with Bulma CSS
Building a simple ToDo list application in React
Using this tutorial https://medium.com/javascript-in-plain-english/build-a-simple-todo-app-with-react-561579b39ad1
And building this app here https://codepen.io/wilstaley/pen/KKwypJW
This is a master project containing the following
- API Get/Post/Put/Delete
- Google Calendar API Get/Post/Delete
- React Hooks
- Jwt Authentication Tokens
- Navbars
- Event Tracking eg Mouse Events
after 4 years of dormancy just seeing if i can update all the libraries etc on this one
so ... clone to master-02
this fails ...
pnpm install
pnpm start so lets start again
pnpm create react-app master-02 --template typescript
cd master-02next i delete package-lock.json and node_modules
next i get the package.json from the old project and have a look at it
i can see the following libraries are not installed so i install them
pnpm add react-router-dom axios js-cookie react-cookie react-cookies reactstrap
// not sure if we need this
pnpm add bootstrapthis adds the libraries and builds a new pnpm-lock.yaml file
now install and run
pnpm install && pnpm startthis now renders out base typescript react app
now have to see what i can migrate over from the old app
first thing i have to put in is router functionality
so we add in index.js
import { BrowserRouter } from "react-router-dom";
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);we now have a functioning app
we now have recovered the basic app and now want to add back in all of the components which were listed in the original master-01 now that we have rebuilt a fresh react app skin and got basic routes and components working fine ...
so ... let's see if we can slowly add in components and see what happens ...
... copied over all the files from master-02 as a starting point ...
pnpm install && pnpm startapp is not perfect but it's building fine ... let's add some components ...
lifecycle methods in a class
// after component mounted
componentDidMount(){}
componentWillUnmount(){}
// this updates any time any part of the component updates
componentDidUpdate(){}lifecycle methods in hooks
import React, {useState, useEffect} from 'react'
export default function MyComponent(props){
const [name, setName] = useState('some name');
// runs after initial render and after every update
useEffect(()=>{
// add javascript here to update whenever any part of the component updates
// for example could asynchronously update an api
axios.POST(url,name)...
})
return(<></>)
}This is probably a whole new repo in itself but I am going to make a start here!
starting here
https://nextjs.org/learn/dashboard-app/getting-started
starter code
https://github.com/vercel/next-learn/tree/main/dashboard/starter-example
brew install node@20install these tools in this order
- winget
- powershell preview
- chocolatey
// winget check version
winget -v
// v1.8.1911
// powershell check version
winget search Microsoft.Powershell
// Name Id Version Source
// ---------------------------------------------------------------
// PowerShell Microsoft.PowerShell 7.4.4.0 winget
// PowerShell Preview Microsoft.PowerShell.Preview 7.5.0.3 winget
//
// winget install latest powershell preview version
winget install --id Microsoft.Powershell.Preview --source winget
//
choco upgrade chocolatey
// check version
choco
// v2.3.0choco install nodejs-lts --version="20.16.0"
node -v
// v20.16.0
npm -v
// 10.8.2npm -v
sudo npm install -g pnpm -ynpx create-next-app@latest nextjs-dashboard --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example" --use-pnpm
cd into project folder then run
pnpm i
pnpm dev
open -a "Microsoft Edge" -u http://localhost:3000
npx create-next-app@latest nextjs-dashboard --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example" --use-pnpm && mv nextjs-dashboard nextjs-dashboard-02 && cd nextjs-dashboard-02 && pnpm i && pnpm dev
css applies
xs={6}
sm={3}
md={2}
lg={1} for a grid setup if we have
<Row>
<Col xs={12} sm={3} md={2} lg={1} />
<Col xs={6} sm={6} md={8} lg={10} />
<Col xs={6} sm={3} md={2} lg={1} />
</Row>then for extra small screen the column ratios with be 12:6:3, on small it will be 3:6:3, medium 2:8:2, large 1:10:1
breakpoints are as follow
xs 576px
sm 768px
md 992px
lg 1200pximages are served as static assets from the /public folder
old html
<img src="my-image.png" />next js
import Image from 'next/image';
export default function Page() {
return (
// ...
<div
<Image
src="/hero-desktop.png"
width={1000}
height={760}
className="hidden md:block"
alt="Screenshots of the dashboard project showing desktop version"
/>
>
});next/image
// or an extension of the html <img> tag
<Image> page.tsx is default page
layout.tsx holds default routes and creates a page common across child routes ie a parent container
when we use the components eg we use partial rendering where only the page body updates, not the side menus, when we navigate
page nav body1 body2
when we navigate from page 1 to page 2, only the body1 or body2 items update
we use next/link to navigate
we use <Link href="…"> instead of ` tags
using clsx we see that the active link is now highlighted so the user knows which page they are on
we are using @vercel/postgres database here for this demo but any database can be used
on vercel project click storage and create a postgres database
give your database a name
nextjs-dashboard-postgresconnect to the database
in .env.local tab click show secret and copy the data
update the contents into the .env file in the project root
next run
pnpm i @vercel/postgresto install the postgres database hosted by vercel
next, seed the database
we use react server components
static - data fetch and render all takes place on server, result is cached
dynamic - data freshly rendered on the server for every request
we use loading.tsx and <Suspense> to stream data
to show 'loading text while a page is loading we use'
export default function Loading() {
return <div>Loading...</div>;
}we see an error on the current version and wish to upgrade
Next.js (15.0.0-canary.56) is outdated
can try this first
remove old dependencies
- node_modules
- pnpm-lock.yaml
then try
yarn upgrade react@canary react-dom@canarythis did not work so backtracking slightly
... trying this ...
firstly upgrade react
yarn add --exact react@rc react-dom@rcthen also nextjs
yarn add next@canarystill having unmet dependencies so try this
yarn add react@canary react-dom@canary next@canary next-auth@canary ... first remove node_modules and any lock files and also remove any references to the four libraries in package.json
in summary to upgrade a project to latest version of react and canary we run
pnpm install && pnpm add react@rc react-dom@rc next@canary next-auth@canary && pnpm devbut first remove
- node_modules
- any lock files
- any reference to
reactreact-domnextjsnextjs-authinpackage.json
ok let's get this one upgraded also ...
as before we now have the quick version so let's try it
- commit any pending work so we have a clean sheet before we begin, in case of disaster then it becomes trivial to roll back
- remove node_modules
- remove any lock files
- remove any reference to
reactreact-domnextjsnextjs-authinpackage.json - run this command
pnpm install && pnpm add react@rc react-dom@rc next@canary next-auth@canary && pnpm devlet's try this on next js dashboard 02 css app
yes! works first time !!!
repeat same steps as above to upgrade to latest canary and rc versions for next js and react js respectively
- commit any pending work so we have a clean sheet before we begin, in case of disaster then it becomes trivial to roll back
- remove node_modules
- remove any lock files
- remove any reference to
reactreact-domnextjsnextjs-authinpackage.json - run this command
pnpm install && pnpm add react@rc react-dom@rc next@canary next-auth@canary && pnpm devyes! works first time, perfect!!!
ok so should be trivial now to also upgrade 04 05 and 06 in the same way
same steps again
- git commit all work to allow for roll back if necessary
- remove node_modules
- remove any lock files
- remove any reference to
reactreact-domnextjsnextjs-authinpackage.json - run this command
pnpm install && pnpm add react@rc react-dom@rc next@canary next-auth@canary && pnpm devimage same as previous 03 version
- git commit all work to allow for roll back if necessary
- remove node_modules
- remove any lock files
- remove any reference to
reactreact-domnextjsnextjs-authinpackage.json - run this command
pnpm install && pnpm add react@rc react-dom@rc next@canary next-auth@canary && pnpm devimage same as previous 03/04 versions ... visible gui unchanged ... ** check actually - was the database working! I think it was !!! **
repeat again same steps
all working !!!
happy days, upgraded whole app!!!
see testing notes and testing folder






