- Notifications
You must be signed in to change notification settings - Fork0
jacobporci/reactjs-twist-tutorial
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
- Library are like pieces of furniture that add style and function to an already constructed house
- Frameworks, on the other hand, are a template you use to build the house itself.
- JSX (Javascript XML)
- Components (pure functions)
- state
- props
- Virtual DOM
- changes happens virtually before replacing actual DOM (lightweight)
- Framework
- NextJS (create-next-app)
Create a boilerplate usingcreate-next-app
- Create a
pages
folder undersrc
- Create an
index.tsx
file undersrc/pages
with this content:exportdefaultfunctionHome(){return(<div><h1>Home</h1></div>);}
- `pages`` folder servers as routing for NextJS
index.tsx
always serves as the displayed page in the route- it's important toALWAYS use
export default
in page components (otherwise NextJS will not see it as a page)
- Create another folder inside
pages
namedtwist
and anotherindex.tsx
undersrc/pages/twist
with content:exportdefaultfunctionTwist(){return(<div><h1>Twist</h1></div>);}
- In your browser, navigate to
localhost:3000/twist
- Create another file inside
src/pages/twist
namedresources.tsx
with content:exportdefaultfunctionResources(){return(<div><h1>Resources</h1></div>);}
In
src/pages
, create a file named_app.tsx
_app.tsx
serves as the root file for all pages, anything displayed here will be displayed in all pages
import{AppProps}from"next/app";importLinkfrom"next/link";exportdefaultfunctionApp({ Component}:AppProps){return(<div><divstyle={{display:"flex",gap:"12px"}}><Linkhref="/">Home</Link><Linkhref="/twist">Twist</Link><Linkhref="/resources">Resources</Link></div><Component/></div>);}
<Component />
is the component page rendered in each route (e.g.src/pages/twist.tsx
)
Try clicking the links at the top of your webpage to see how it works
- Create a
components
folder insidesrc
- Create a file named
button.tsx
insidesrc/components
with content:exportconstButton=()=>{return<button>Click me</button>;};
- Import the
Button
component in your homepage and place it below theHello
- components can be
- self-closed
<Button />
- paired
<Button></Button>
- self-closed
- check if it is rendered in your homepage
- NextJS handlesaliased imports
@/components/whatever
- components can be
- object that triggers a re-render
- basically short for
property
In your Home page file(
src/pages/index.tsx
), create a state to count the number of times a button is clicked- place it above the
return
statement
const[clicks,setClicks]=useState(0);
- don't forget to import
useState
- place it above the
Go to
src/components/button.tsx
, and declare yourprops
type (used to bePropTypes in base ReactJS)typeButtonProps={onClick:()=>void,};
Add the type declaration to your component params and deconstruct your
props
:- you should see anintellisense for your
onClick
method when you clickCTRL +Space in your keyboard
exportconstButton=({ onClick}:ButtonProps)=>{
- you should see anintellisense for your
Assign the
onClick
prop to your button'sonClick
event listener prop:return<buttononClick={onClick}>Click me</button>;
Go back to
src/pages/index.tsx
and assign thesetClicks
method to your button'sonClick
prop, and show theclicks
state above the button<p>Clicks:{clicks}</p><ButtononClick={()=>setClicks(clicks+1)}/>
Click the
Click Me
button a couple of times and see how the count reacts
state can be handled in many ways:
- useState
- useContext
- useReducer
- Redux
- etc.
In this example, we're going to explore where to best place the state and which state management tool to use best
used to expose state in a given context
solution for
prop drilling
passing state from component to component until you reach the component where you want to use that state
example: passing the
count
prop in this manner- _app.tsx
const[count]=useState();return<Componentcount={count}>
- index.tsx
constHome=({ count})=>(<Headercount={count}>)
- header.tsx
constHeader=({ count})=>(<Contentcount={count}>)
- content.tsx
constContent=({ count})=><p>{count}</p>;
instead, we can just do this:
_app.tsx
exportconstCountContext=createContext(0);functionApp(){const[count]=useState();return(<CountContext.Providervalue={clicks}><div><h1>Home</h1><p>Clicks:{clicks}</p><ButtononClick={()=>setClicks(clicks+1)}/></div></CountContext.Provider>);}
content.tsx
import{CountContext}from"@/pages";constContent=()=>{constcount=useContext(CountContext);return<p>{count}</p>;};
useReducer is a clone ofRedux
- state
- action
- type
- payload
- used to promote logic and state reusability
- hooks are basically
components
that returns whatever you want
example:insrc/hooks/useCount.tsx
import{useState}from"react";exportconstuseCount=({ defaultCount=0}:{defaultCount?:number})=>{const[count,setCount]=useState(defaultCount);return{ count, setCount};};
insrc/pages/index.tsx
,instead of declaring:
const{ clicks, setClicks}=useCount({defaultCount:1});
we can import theuseCount
hook instead
import{useCount}from"@/hooks/useCount";exportdefaultfunctionHOME(){const{ clicks, setClicks}=useCount({defaultCount:1});
Frameworks I've used:
- Material UI
- probably the most famous UI library
- Chakra-UI
- simple and has aTailwindCSS like way of adding styles
- TailwindCSS
- used to just add classNames of predefined CSS attributes
Things to consider when choosing your UI library
- Mobile-friendly
- Accessibility
- aria-roles
- aria-labels
- important when unit testing
- Support
7.Axios
- HTTP client for node and browser
Create only 1 axios instance for consistency and just import the created axios instance
constapi=axios.create({baseURL:"localhost:3000/api",});
- Cypress
- more versatile
- React Testing Library
- for unit testing