React
Create a React app
Chrome extension => React Dev Tools
“Old”
# Instalar utilitário para criar base da aplicação
node install --global create-react-app
# Criar aplicação
create-react-app NOMEAPP
cd NOMEAPP
# Iniciar servidor de desenvolvimento
npm start
# Cria pacote para produção
npm run build
# Executa testes
npm test
“New”
npx create-react-app react-task-tracker
cd react-task-tracker
npm start
Files & folders
src/App.js
:
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
Hello World
</div>
);
}
}
App component & JSX
Expressions in JSX
JSX:
class -> className
for -> htmlFor
Creating a component
VScode extension: ES7 React/Reduct/GraphQL/React-Native snippets
snippet: rafce -> React Arrow Function Component Export
Function component
const App = () => {
return (
<h1>Hello</h1>
)
}
Class component
import React
class App extends React.Component {
render() {
return <h1>Hello</h1>
}
}
Component Props
import PropTypes from 'prop-types'
const Header = (props) => {
return (
<h1>{props.title}</h1>
)
}
Header.defaultProps = {
title: 'Task Tracker',
}
export default Header
PropTypes
Header.propTypes = {
title: PropTypes.string.isRequired,
}
Styling
<h1 style=>props.title</h1>
<h1 style={alternativeStyle}>props.title</h1>
const alternativeStyle = {
color: 'red',
backgroundColor: 'white',
};
Button Component & Event
import PropTypes from 'prop-types'
const Button = ({color, text, onClick}) => {
return (
<button style=
className='btn'
onclick='onClick'>{text}</button>
)
}
Button.defaultProps = {
color: 'steelblue',
}
Button.propTypes = {
text: PropTypes.string,
color: PropTypes.string,
onClick: PropTypes.func //.isRequired
}
Component with children
const Tasks = ({tasks}) => {
return (
<>
{tasks.map((task) => { <h3 key={task.id}>{task.text}</h3> }}
</>
)
}
State & useState Hook & Global state
At src/App.js:
import { useState } from 'react'
const [tasks, setTasks] = useState([...])
Icons with react-icons
npm install react-icons
import { FaTimes } from 'react-icons'
...
<h3>{task.text} <FaTimes style=/></h3>
...
Delete item on state
const deleteTask = (id) => {
setTasks(tasks.filter((task) => task.id !== id)
}
Optional message if no items
{ tasks.length > 0 ? <Tasks...> : 'No tasks' }
JSON Server
npm i json-server
"scripts": {
"server": "json-server --watch db.json --port 5000"
}
CRUD operations
useEffect Hook & Fetch data from server
useEffect(() => {
getTasks();
}, [])
const fetchTasks = async () => {
const res = await fetch(`http://localhost:5000/tasks`)
const data = await res.json()
return data
}
Delete
const deleteTask = async (id) => {
await fetch(`http://localhost:5000/tasks/${id}`, {method: 'DELETE'})
}
Create
const addTask = async (task) => {
const res = await fetch(`http://localhost:5000/tasks`, {
method: 'POST',
headers: {'Content-type': 'application/json'},
body: JSON.stringify(task)
})
const data = await res.json()
return data
}
Update
const fetchTask = async (id) => {
const res = await fetch(`http://localhost:5000/tasks/${id}`)
const data = await res.json()
return data
}
const toggleReminder = async (task) => {
const taskToToggle = await fetchTask(id)
const updTask = {...taskToToggle, reminder: !taskToToggle.reminder}
const res = await fetch(`http://localhost:5000/tasks`, {
method: 'PUT',
headers: {'Content-type': 'application/json'},
body: JSON.stringify(updTask)
})
const data = await res.json()
setTasks(...)
}
Routing, footer & about
Routing
npm install react-router-dom
import { BrowserRouter as Router, Route} from 'react-router-dom'
<Router>
<Route path='/' exact render={(props) => (<> ... </>)}>
<Route path='/about' component={About}>
</Router>
Linking to routes
import { Link } from 'react-router-dom'
Replace: <a href='...'>Example</a>
With: <Link to='...'>Example</Link>
Keep track of current route
import { useLocation } from 'react-router-dom'
const location = useLocation();
{ location.pathname === '/' && (<Button ... />) }