Credit: Eric The Coder
// Create a new app
npx create-react-app my-app-name
// Run the created app
cd my-app-name
yarn start
// http://localhost:3000
- No need to import React from 'react' (since React 17)
- Must have uppercase first letter
- Must return JSX (src/App.js)
// React component
function App(){
return <h1>Hello World</h1>
}
export default App;
How this component get render to the browser? The main project file is src/index.js and in that file there are instruction to render the component
ReactDOM.render(<App />, document.getElementById('root'))
function Greeting(){
return <h1>Hello World</h2>
}
export default Greeting
import Greeting from './Gretting'
function App(){
return <Greeting />
}
export function Greeting(){
return <h1>Hello World</h2>
}
import {Greeting} from './Gretting'
return (
<div className="app">
<h1 className="app_title">Welcome to my application: {appTitle}</h1>
<div className="product">
<h1 className="product__name--large">Product name: {product.name}</h1>
<h1 className="product__name--small">Nick name: {product.nickName}</h1>
<p className="product__description">Product description: {product.description}
</div>
<div>
)
// not valid
return <h1>Hello world</h1><h2>Hi!</h2>
// valid with fragment.
return (
<>
<h1>Hello World</h1>
<h2>Hi!</h2>
</>
)
// Noted the parenthesis for multi-line formatting
// not valid
return (
<div class="title">
Hello World
</div>
)
// valid
return (
<div className="title">
</div>
)
return (
<img src="http:example.com/image.jpg" />
<input type="text" name="first_name" />
)
// Arrow function shorthand component
const Person = () => <h1>Mike Taylor</h1>
// Arrow function component
const Message = () => {
return <h1>Hello</h1>
}
// Function component
function HelloWorld(){
return (
<>
<Message />
<Person />
</>
)
}
(src/App.css)
h1 {
color: red;
}
(src/App.js)
import './App.css'
function App(){
return <h1>Hello World</h1>
}
function App(){
return <h1 style={{ color: 'red' }}>Hello World</h1>
}
- Enclose between {}
- Must be an expression (return a value)
function App(){
const name = 'Mike'
return (
<>
<h1>Hello {name}</h1>
<p>{name === 'Mike' ? '(admin)': '(user)'}</p>
</>
)
}
function App()
return <Person name='Mike' age={29} />
}
const Person = (props) => {
return <h1>Name: {props.name}, Age: {props.age}</h1>
}
// or props object deconstructing
const Person = ({name, age}) => {
return <h1>Name: {name} Age: {age}</h1>
}
function App()
return (
<Person name='Mike' age={29}>
Hi, this is a welcome message
</Person>
)
}
const Person = (props) => {
return (
<h1>Name: {props.name}, Age: {props.age}</h1>
<p>{props.children}</p>
)
}
// or props object deconstructing
const Person = ({name, age, children}) => {
return (
<h1>Name: {name} Age: {age}</h1>
<p>{children}</p>
)
}
const Person = ({name, age, children}) => {
return (
<h1>Name: {name} Age: {age}</h1>
<p>{children}</p>
)
}
Person.defaultProps = {
name: 'No name',
age: 0,
}
const people = [
{id: 1, name: 'Mike', age: 29},
{id: 2, name: 'Peter', age: 24},
{id: 3, name: 'John', age: 39},
]
function App(){
return (
people.map(person => {
return <Person name={person.name} age={person.age}/>
})
)
}
const Person = (props) => {
return (
<h1>Name: {props.name}, Age: {props.age}</h1>
)
}
function App(){
return (
people.map(person => {
return <Person key={person.id} name={person.name} age={person.age}/>
})
)
}
function App(){
return people.map(person => <Person key={person.id} {...person} />)
}
const Person = ({name, age}) => {
return (
<h1>Name: {name}, Age: {age}</h1>
)
}
const clickHandler = () => alert('Hello World')
function App(){
return (
<>
<h1>Welcome to my app</h1>
<button onClick={clickHandler}>Say Hi</button>
</>
)
}
function App(){
return (
<>
<h1>Welcome to my app</h1>
<button onClick={ () => alert('Hello World') }>Say Hi</button>
</>
)
}
const clickHandler = (message) => alert(message)
function App(){
return (
<>
<h1>Welcome to my app</h1>
<button onClick={() => clickHandler('Hello World')}>Say Hi</button>
</>
)
}
const clickHandler = (e) => console.log(e.target)
function App(){
return (
<>
<h1>Welcome to my app</h1>
<button onClick={clickHandler}>Say Hi</button>
</>
)
}
function Todo({item, onDelete}) {
return (
<div>
{item}
<button onClick={() => onDelete(item)}
</div>
)
}
function Todos() {
const handleDelete = (todo) => {
const newTodos = todos.filter(item => item !== todo)
setTodos(() => newTodos)
}
return (
{todos.map(todo => (
<Todo item={todo} onDelete={handleDelete}/>
}
)
}
The purpose of useState is to handle reactive data. any data that changes in the application is called state. And when the state changes, you want react to update the UI.
- Hook always start with 'use' prefix
- Must be invoke only in a React component/function
- Must be call at top level of a functional component
- Declaration cannot be call conditionally
- useState return an array of 2: [state value, set state function]
import React, {useState} from 'react';
const DisplayTitle = () => {
const [title, setTitle] = useState('This is the Title')
const handleClick = () => setTitle('New Title')
return <>
<h2>{title}</h2>
<button type="button" className="btn" onClick={handleClick}>
Change Title
</button>
</>
};
export default DisplayTitle;
const DisplayTitle = () => {
const [person, setPerson] = useState({name: 'Mike', age: 29})
const handleClick = () => setPerson({...person, age: 35})
return <>
<h2>{title}</h2>
<button type="button" className="btn" onClick={handleClick}>
Change Age
</button>
</>
};
function Counter() {
const [count, setCount] = useState(0)
// Use a function to set State
const increase = () => setCount(() => count + 1)
return (
<>
<h1>Counter</h1>
<p>{count}</p>
<button onClick={increase} className='btn'> + </button>
<button onClick={() => setCount(() => count - 1)} className='btn'> - </button>
</>
)
}
In React you may want to execute code after lifecycle events or side effects.
By default useEffect function is execute after every re-render. You can then execute code everytime component update. import React, { useEffect } from 'react';
function IncreaseValue() {
const [value, setValue] = useState(0)
useEffect(() => {
document.title = `New value: ${value}`
})
return <button onClick={() => setValue(value + 1)}>Increase</button>
}
useEffect(() => {
if (value > 0) {
document.title = `New value: ${value}`
}
})
What if you want to execute code only on first render or only when a particular state change? You can use the useEffect function and send an array of dependencies as parameter.
useEffect(() => {
document.title = `New value: ${value}`
}, [])
// Noted the empty array. useEffect will then only run once on initial render
useEffect(() => {
document.title = `New value: ${value}`
}, [value])
// Will run each time 'value' state change.
To execute code only when a component is unmount/destroy you need to add a 'return' statement to your useEffect function.
useEffect(() => {
const timer = window.setInterval(() => {
setCount(count => count + 1)
}, 1000)
return () => clearInterval(timer)
}, [])
function DisplayGreeting() {
const [name, setName] = useState('Mike')
if (name === 'Mike') {
return <h1>Hello admin {name}</h1>
}
return <h1>Hello user {name}</h1>
}
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
function DisplayUserInfo({active}) {
return (
<div>
{ active && <h1>User is active</h1>}
</div>
);
}
<span className={count === 0 && 'text-gray-500' || count > 0 && 'text-green-500' || count < 0 && 'text-red-500'}>{count}</span>
const UserForm = () => {
const [userName, setUserName] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
console.log(userName)
}
return (
<>
<form onSubmit={handleSubmit}>
<input
value={userName}
onChange={(e) => setUserName(e.target.value)}
type="text" id="userName"
name="userName"
/>
<button type="submit">Submit</button>
</form>
</>
)
};
export default UserForm;
useRef is mostly use to target a DOM element. But it can also be use to keep/preserve a mutable value between each render. useRef does not trigger a re-render (like a useState).
const UseRefBasics = () => {
const refContainer = useRef(null)
const handleSubmit = (e) => {
e.preventDefault()
console.log(refContainer.current.value)
}
useEffect(() => {
refContainer.current.focus()
}, [])
return (
<div>
<form className="form" onSubmit={handleSubmit}>
<div>
<input ref={refContainer} type="text" />
<button type="submit">Submit</button>
</div>
</form>
</div>
)
};