Skip to content

Implementando a Criação de Anotações

Vamos criar um componente para o formulário de criação.

  1. Crie o arquivo src/components/Formulario/index.jsx com o seguinte conteúdo:
import "./index.css";

export default function Formulario() {

    return (
        <form className="form-card">
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

Crie o arquivo src/components/Formulario/index.css e coloque o estilo CSS das classes form-card, form-card-title e btn utilizado nos projetos anteriores.

Adicionando componente Formulario no App

Precisamos adicionar o componente Formulario no src/App.jsx. Podemos pensar no componente como uma função javascript que retorna html. Para utilizar um componente, basta colocar o nome dele entre tags, como se fosse uma tag HTML. Veja o exemplo abaixo:

import axios from "axios";
import { useEffect, useState } from "react";
import Note from "./components/Note";
import AppBar from "./components/AppBar";
import Formulario from "./components/Formulario";
import "./App.css";

function App() {
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    axios
      .get("http://localhost:8000/notes/")
      .then((res) => setNotes(res.data));
  }, []);

  return (
    <>
      <AppBar />
      <main className="container">
        <Formulario />
        <div className="card-container">
          {notes.map((note) => (
            <Note key={`note__${note.id}`} title={note.title}>
              {note.content}
            </Note>
          ))}
        </div>
      </main>
    </>
  );
}

export default App;

Armazenado valor digitado pelo usuário nos Inputs

Vamos armazenar os valores digitados pelo usuário nas variáveis titulo e conteudo. Para isso, vamos criar duas variáveis utilizando useState do React;

import { useState } from "react";
import "./index.css";

export default function Formulario() {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    return (
        <form className="form-card" method="post">
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

As variáveis inicialmente começam como strings vazias "". Conforme o usuário digita algum valor nos campos inputs, o valor das variáveis é atualizado. Para isso podemos utilizar o atributo onChange do HTML, veja o exemplo abaixo:

import { useState } from "react";
import "./index.css";

export default function Formulario() {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    return (
        <form className="form-card" method="post">
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
                onChange={(event) => console.log(event.target.value)}
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}
Sempre que o usuário interagir com o campo input o evento onChange chamará a função (event) => console.log(event.target.value). O parâmetro event é o evento que ocorreu, e event.target.value é o valor digitado pelo usuário. Vamos fazer um teste para verificar se o valor digitado está sendo armazenado corretamente. Digite algo no campo input e veja o valor no console do navegador.

Valor digitado no console
Valor digitado no console

Vamos alterar a função onChange para armazenar o valor digitado pelo usuário na variável titulo. Para isso, vamos utilizar a função setTitulo passando o valor digitado pelo usuário event.target.value.

import { useState } from "react";
import "./index.css";

export default function Formulario() {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    return (
        <form className="form-card" method="post">
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
                onChange={(event) => setTitulo(event.target.value)}
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
                onChange={(event) => setContent(event.target.value)}
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

Enviar os dados para o servidor

Agora vamos enviar os dados para o servidor. Para isso, vamos utilizar o atributo onSubmit do HTML. Veja o exemplo abaixo:

O comando event.preventDefault() previne que o formulário seja enviado para o servidor. Assim, podemos enviar os dados utilizando o axios.

import axios from "axios";
import { useState } from "react";
import "./index.css";

export default function Formulario() {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    const criarNote = (event) => {
        event.preventDefault();

        const data = {
            "title": titulo,
            "content": content
        }

        axios
            .post("http://localhost:8000/notes/", data)
            .catch((error) => console.log(error));
    }

    return (
        <form className="form-card" onSubmit={criarNote}>
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
                onChange={(event) => setTitulo(event.target.value)}
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
                onChange={(event) => setContent(event.target.value)}
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

Tente criar uma nova anotação! Parece que não está funcionando, certo? Se atualizar a página, perceberá que anotação foi criada, porém a página não foi atualizada. Vamos resolver isso!

Atualizando a lista de anotações

Agora que já enviamos os dados para o servidor, precisamos atualizar a lista de anotações. Se olharmos o código do arquivo src/App.jsx queremos executar o código contido nas linhas marcadas abaixo, pois queremos atualizar a lista de anotações.

import axios from "axios";
import { useEffect, useState } from "react";
import Note from "./components/Note";
import AppBar from "./components/AppBar";
import Formulario from "./components/Formulario";
import "./App.css";

function App() {
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    axios
      .get("http://localhost:8000/notes/")
      .then((res) => setNotes(res.data));
  }, []);

  return (
    <>
      <AppBar />
      <main className="container">
        <Formulario />
        <div className="card-container">
          {notes.map((note) => (
            <Note key={`note__${note.id}`} title={note.title}>
              {note.content}
            </Note>
          ))}
        </div>
      </main>
    </>
  );
}

export default App;

Para isso, vamos mover esse trecho de código para dentro de uma função, para que possamos enviar essa função para o componente Formulario.

import axios from "axios";
import { useEffect, useState } from "react";
import Note from "./components/Note";
import AppBar from "./components/AppBar";
import Formulario from "./components/Formulario";
import "./App.css";

function App() {
  const [notes, setNotes] = useState([]);

  const carregaNotas = () => {
    axios
      .get("http://localhost:8000/notes/")
      .then((res) => setNotes(res.data));
  }

  useEffect(() => {
    carregaNotas();
  }, []);

  return (
    <>
      <AppBar />
      <main className="container">
        <Formulario />
        <div className="card-container">
          {notes.map((note) => (
            <Note key={`note__${note.id}`} title={note.title}>
              {note.content}
            </Note>
          ))}
        </div>
      </main>
    </>
  );
}

export default App;

Vamos enviar a função carregaNotas para o componente Formulario utilizando o nome loadNotes. Lembra que os componentes são funções javascript? Em alguns casos, vamos querer passar um argumento para a função.

Em nosso casso, estamos querendo passar a função carregaNotas como argumento para a função/componente Formulario.

import axios from "axios";
import { useEffect, useState } from "react";
import Note from "./components/Note";
import AppBar from "./components/AppBar";
import Formulario from "./components/Formulario";
import "./App.css";

function App() {
  const [notes, setNotes] = useState([]);

  const carregaNotas = () => {
    axios
      .get("http://localhost:8000/notes/")
      .then((res) => setNotes(res.data));
  }

  useEffect(() => {
    carregaNotas();
  }, []);

  return (
    <>
      <AppBar />
      <main className="container">
        <Formulario loadNotes={carregaNotas}/>
        <div className="card-container">
          {notes.map((note) => (
            <Note key={`note__${note.id}`} title={note.title}>
              {note.content}
            </Note>
          ))}
        </div>
      </main>
    </>
  );
}

export default App;

Chamando a função carregaNotas no componente Formulario

O componente Formulario recebe o argumento props que contém todas as informações enviadas para o componente. Como enviamos a função carregaNotas com o nome de loadNotes, para chamar a função carregaNotas dentro do componente Formulario utilizamos o comando props.loadNotes().

import axios from "axios";
import { useState } from "react";
import "./index.css";

export default function Formulario(props) {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    const criarNote = (event) => {
        event.preventDefault();

        const data = {
            "title": titulo,
            "content": content
        }

        axios
            .post("http://localhost:8000/notes/", data)
            .then((response) => props.loadNotes())
            .catch((error) => console.log(error));
    }

    return (
        <form className="form-card" onSubmit={criarNote}>
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
                onChange={(event) => setTitulo(event.target.value)}
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
                onChange={(event) => setContent(event.target.value)}
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

Limpando os valores dos campos do Formulário

Ao criar uma nova anotação, os dados estão sendo salvos no banco de dados pela API Django REST e a página é atualizada com a nota anotação aparecendo na página. Porém, os campos do formulário não estão sendo limpos. Para limpar os campos do formulário, basta atualizar as variáveis titulo e content com o valor "" (string vazia). Além disso, é necessário utilizar essas variáveis para definir o valor dos campos do formulário. Veja o exemplo abaixo:

import axios from "axios";
import { useState } from "react";
import "./index.css";

export default function Formulario(props) {
    const [titulo, setTitulo] = useState("");
    const [content, setContent] = useState("");

    const criarNote = (event) => {
        event.preventDefault();

        const data = {
            "title": titulo,
            "content": content
        }

        axios
            .post("http://localhost:8000/notes/", data)
            .then((response) => {
                props.loadNotes();
                setTitulo("");
                setContent("");
            })
            .catch((error) => console.log(error));
    }

    return (
        <form className="form-card" onSubmit={criarNote}>
            <input
                className="form-card-title"
                type="text"
                name="titulo"
                placeholder="Título"
                onChange={(event) => setTitulo(event.target.value)}
                value={titulo}
            />
            <textarea
                className="autoresize"
                name="detalhes"
                placeholder="Digite o conteúdo..."
                onChange={(event) => setContent(event.target.value)}
                value={content}
            ></textarea>
            <button className="btn" type="submit">Criar</button>
        </form>
    );
}

Deletando uma anotação

Implemente a funcionalidade de deletar uma anotação. Para isso, crie um botão dentro do componente Note que ao ser clicado, envie uma requisição para a API Django REST para deletar a anotação. Após deletar a anotação, atualize a lista de anotações.

Implementando a Edição de Anotações

Para continuar, avance para a próxima etapa.

Implementando a edição de Anotações