Crie um novo projeto React com Vite.
Substitua todos os estilos do arquivo “index.css” pelo código abaixo:
* {
box-sizing: border-box;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
#app {
background-color: #eaeaea;
border-radius: .25rem;
margin: 2rem auto;
padding: 2rem 4rem;
max-width: 32rem;
}
label {
display: block;
margin-bottom: .5rem;
}
input,
textarea,
button {
display: block;
font-size: 1rem;
margin-bottom: 1rem;
padding: .5rem;
width: 100%;
}
Comece criando a estrutura da seção de comentários:
export default function App() {
return (
<div id="app">
<h2>Seção de Comentários</h2>
<form>
<label htmlFor="author">Email</label>
<input type="text" id="author" required />
<label htmlFor="content">Comentário</label>
<textarea id="content" cols="30" rows="6" required></textarea>
<button>Enviar comentário</button>
</form>
<hr />
<section id="comments">
<div>
<h3>[email protected]</h3>
<span>Em 01/01/2001</span>
<p>Comentário de exemplo</p>
</div>
</section>
</div>
)
}
Crie dois estados para controlar os inputs de autor e conteúdo do comentário:
import { useState } from "react"
export default function App() {
const [author, setAuthor] = useState("")
const [content, setContent] = useState("")
return (
<div id="app">
<h2>Seção de Comentários</h2>
<form onSubmit={handleSubmit}>
<label htmlFor="author">Email</label>
<input
type="text" id="author" required
value={author} onChange={(e) => setAuthor(e.target.value)}
/>
<label htmlFor="content">Comentário</label>
<textarea
id="content" cols="30" rows="5" required
value={content} onChange={(e) => setContent(e.target.value)}
></textarea>
<button>Enviar comentário</button>
</form>
<hr />
// ...
Adicione a função que irá salvar o comentário no evento onSubmit:
import { useState } from "react"
export default function App() {
const [author, setAuthor] = useState("")
const [content, setContent] = useState("")
const handleSubmit = (e) => {
e.preventDefault()
const newComment = {
id: Math.floor(Math.random() * 1000000),
author: author,
content: content,
createdAt: new Date()
}
console.log({ newComment })
setAuthor("")
setContent("")
}
return (
<div id="app">
<h2>Seção de Comentários</h2>
<form onSubmit={handleSubmit}>
<label htmlFor="author">Email</label>
// ...
Por fim, crie o estado para armazenar os comentários e a renderização condicinal da lista de comentários:
import { useState } from "react"
export default function App() {
const [comments, setComments] = useState([])
const [author, setAuthor] = useState("")
const [content, setContent] = useState("")
const handleSubmit = (e) => {
e.preventDefault()
const newComment = {
id: Math.floor(Math.random() * 1000000),
author: author,
content: content,
createdAt: new Date()
}
setComments(state => [newComment, ...state])
setAuthor("")
setContent("")
}
return (
<div id="app">
<h2>Seção de Comentários</h2>
<form onSubmit={handleSubmit}>
<label htmlFor="author">Email</label>
<input type="email" id="author" required value={author} onChange={(e) => setAuthor(e.target.value)} />
<label htmlFor="content">Comentário</label>
<textarea id="content" cols="30" rows="5" required value={content} onChange={(e) => setContent(e.target.value)}></textarea>
<button>Enviar comentário</button>
</form>
<hr />
<section id="comments">
{comments.length > 0
? (
comments.map((comment) => (
<div key={comment.id}>
<h3>{comment.author}</h3>
<span>Em {comment.createdAt.toLocaleString()}</span>
<p>{comment.content}</p>
</div>
)))
: (
<p>Seja o primeiro a comentar!</p>
)}
</section>
</div>
)
}