Last Updated: 2021-03-31
O React é uma biblioteca JavaScript. Não é Framework, embora muitos se referem a ele assim. É importante ter um conhecimento básico da linguagem JavaScript.
Você tem basicamente dois caminhos para construir suas aplicações React:
Usa as bibliotecas online e um editor baseado em navegador. Vamos usar aqui o codepen.io com este código inicial
Veja as configurações necessárias para usar React no codepen.io
https://unpkg.com/react/umd/react.development.js
https://unpkg.com/react-dom/umd/react-dom.development.js
Vamos usar o VSCODE, mas é possível usar qualquer ide moderna tal como: Eclipse, Intellij IDEA, etc.
npx create-react-app aula
Depois de algum tempo você verá:
c:\React>cd aula
c:\React>code .
Para abrir o vscode. Você deverá ver o seguinte
O Chrome irá abrir uma página usando a URL http://localhost:3000/ e a app estará rodando assim:
A guia mostra os componentes raiz do React que foram renderizados na página, bem como os subcomponentes que eles acabaram renderizando. Ao selecionar um dos componentes na árvore, você pode inspecionar e editar seus adereços e estado atuais no painel à direita. Na localização atual, você pode inspecionar o componente selecionado, o componente que o criou, o componente que o criou e assim por diante.
Abra outro terminal no vscode e delete todos os arquivos da pasta src.
c) 2020 Microsoft Corporation. Todos os direitos reservados.
C:\React>cd aula
C:\React\aula>cd src
C:\React\aula\src>del *
C:\React\aula\src\*, Tem certeza (S/N)? s
C:\React\aula\src>
Crie um arquivo novo chamado index.js na pasta src e insira o código:
import ReactDOM from 'react-dom'
ReactDOM.render(
<h1>Alô mundo!</h1>,
document.getElementById('root')
);
Você verá no browser
Vamos aprender agora os fundamentos das aplicações React: elementos e componentes. Mas antes, como React é uma biblioteca JavaScript, vamos fazer uma breve revisão da linguagem JavaScript.
A principal característica da JavaScript é que as funções são objetos, permitindo às funções a capacidade para armazenar código executável e serem passadas como parâmetro para qualquer outro objeto.
Vamos usar o codepen.io para executar nossos exemplos.
São objetos e representam sequências de caracteres. Exemplos:
console.log("alo2".length);
console.log("alo2".indexOf('l'));
console.log("alo2".toUpperCase());
Estes exemplos mostram como acessar as propriedades e funções de objetos do tipo String. Observe o uso do .
assim como em Java.
Podemos usar as palavras reservadas var, let e const
para declarar variáveis. Se uma variável é definida usando var
dentro de uma estrutura (por exemplo dentro de uma estrutura de controle if), ela será visível por toda a função fora da estrutura. A definição de variáveis usando o let foi introduzida no ECMAScript 6. O let
permite escopo de bloco, ou seja, é possível definir uma variável em um bloco if, e esta variável ter escopo limitado ao bloco if- por exemplo. const
funciona como let
porém seu valor não pode ser alterado.
var name = "kittens";
if (name == "puppies") {
name += "!";
} else if (name == "kittens") {
name += "!!";
} else {
name = "!" + name;
}
name == "kittens!!"
while (true) {
// an infinite loop!
}
var input;
do {
input = get_input();
} while (inputIsNotValid(input))
for (var i = 0; i < 5; i++) {
// Will execute 5 times
}
var allowed = (age > 18) ? "yes" : "no";
switch(action) {
case 'draw':
drawit();
break;
case 'eat':
eatit();
break;
default:
donothing();
}
Objetos JavaScript são simplesmente coleções de pares nome-valor. Como tal, eles são similares à:
As propriedades dos objetos são pares nome-valor. A parte "nome" é uma string JavaScript, enquanto a parte "valor" pode ser qualquer valor JavaScript — incluindo mais objetos. Isso permite que você construa estruturas de dados de qualquer complexidade.
Podemos criar objetos de duas maneiras:
var obj = new
Object();
var obj = {};
As duas maneiras são equivalentes; a segunda forma é chamada de sintaxe de objeto literal e é mais conveniente. Essa sintaxe é também o coração do formato JSON.
Exemplos:
var pessoa = {};
//usando a notação .
pessoa.nome = "Edson";
console.log(pessoa.nome);
//usando notação de mapa associativo
pessoa["sobrenome"] = "Angoti";
console.log(pessoa["sobrenome"]);
A sintaxe de objeto literal pode ser usada para inicializar completamente um objeto:
var conta = {
numero: 123,
agencia: "centro",
detalhes: {
protegida: true,
remunerada: false
}
}
console.log(conta.numero)
console.log(conta["detalhes"]["protegida"])
São objetos em JavaScript. Eles funcionam de forma muito similar à objetos regulares (propriedades numéricas podem naturalmente ser acessadas somente usando a sintaxe [], colchetes ).
Exemplos:
var a = new Array();
a[0] = "dog";
a[1] = "cat";
a[2] = "hen";
console.log(a.length)
var b = ["dog", "cat", "hen"];
console.log(a.length)
Junto com objetos, funções são os componentes principais para o entendimento do JavaScript. A função mais básica não poderia ser mais simples:
function add(x, y) {
var total = x + y;
return total;
}
Os parâmetros podem ser acessados através de uma propriedade chamada arguments
dentro da função. Esta propriedade é um vetor que contém todos os valores passados para a função.
function add() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum;
}
console.log(add(1,2,3,4))
Na POO clássica, objetos encapsulam dados e métodos que operam sobre esses dados. JavaScript é uma linguagem baseada em protótipos que não contém a estrutura de classe, como tem em C++ e Java. Em vez disso, JavaScript usa funções como classes.
Exemplo
function PessoaFisica(nome, sobrenome) {
return {
nome: nome,
sobrenome: sobrenome,
nomeCompleto: function() {
return this.nome + ' ' + this.sobrenome;
}
}
}
var pessoa1 = PessoaFisica("Edson", "Angoti")
console.log(pessoa1.nomeCompleto())
JSX é uma extensão que facilita escrever código HTML no React através da conversão de tags HTML em elementos React.
O exemplo a seguir cria um elemento React:
const elementoReact = <h1>Alô mundo!</h1>;
ReactDOM.render(elementoReact, document.getElementById("root"));
Elementos React são imutáveis, por isso declaramos uma variável usando a palavra reservada const.
Código javascript pode ser inserido em expressões JSX entre chaves. Veja exemplos abaixo:
function PessoaFisica(nome, sobrenome) {
return {
nome: nome,
sobrenome: sobrenome,
nomeCompleto: function () {
return this.nome + " " + this.sobrenome;
}
};
}
const user = PessoaFisica("Edson", "Angoti");
const element = <h1>Hello, {user.nomeCompleto()}</h1>;
ReactDOM.render(element, document.getElementById("root"));
O React DOM usa camelCase como convenção para nomes de propriedades ao invés dos nomes de atributos do HTML. Então o atributo classname para aplicação de CSS é escrito className.
Observe o uso de comentários dentro de um elemento JSX usando {/* comentários */}. Nomes de atributos devem seguir
Entenda um componente React como funções JavaScript que recebem um argumento chamado props
e retornam elementos React que descrevem o que deve aparecer na tela. Podemos criar componentes de duas formas:
function ComponenteSaudacao(props) {
return (
<h1 style={{ background: "red" }}>
Hello, {props.user.nomeCompleto()}
<img
src={props.imgUrl}
width="60"
style={{ margin: "10px 0px 0px 10px" }}
/>
</h1>
);
}
class ComponenteSaudacaoClass extends React.Component {
render() {
return (
<h1 style={{ background: "red" }}>
Hello, {this.props.user.nomeCompleto()}
<img
src={this.props.imgUrl}
width="60"
style={{ margin: "10px 0px 0px 10px" }}
/>
</h1>
);
}
}
Depois que um componente é declarado, você pode chama-lo assim:
ReactDOM.render(
<ComponenteSaudacaoClass user={user} imgUrl={imgUrl} />,
document.getElementById("root")
);
Não importa como você declarou o componente, como função ou classe, a chamada é da mesma forma.
A propriedade props
passada para o componente é um objeto JavaScript, e usando notação JSON pode ser representado assim:
const usuario = PessoaFisica("Edson", "Angoti");
const imagem = "https://miro.medium.com/max/3840/1*vHHBwcUFUaHWXntSnqKdCA.png";
props = { user : usuario, imgUrl : imagem }
Fonte: React documentation
O ciclo de vida de um componente React tem três categorias - Montagem, Atualização e Desmontagem.
render()
é o método de ciclo de vida mais usado. É uma função pura. Você não pode definir/alterar o estado em render(). componentDidMount()
chamado assim que o componente é montado. Você pode definir/alterar o estado aqui.componentDidUpdate()
Este método de ciclo de vida é chamado assim que ocorre atualização. O caso de uso mais comum para o método componentDidUpdate() é atualizar o DOM em resposta a alterações de propriedade ou estado.componenteWillUnmount()
Chamado pouco antes de o componente ser desmontado e destruído. Este é um bom lugar para limpar todos os dados. Você não pode definir o estado aqui. shouldComponentUpdate()
, getDerivedStateFromProps()
e getSnapshotBeforeUpdate()
Para o estudo do ciclo de vida vamos trabalhar com componentes definidos como classe. As propriedades da classe são imutáveis, portanto todos os valores passados para o componente através de props não podem ser alterados. Podemos usar a propriedade state que permite manter o estado do componente e sofrer alterações. Aqui mostramos o construtor do componente onde declaramos o estado do componente.
HTML
<div id="teste"></div>
Javascript
class Contador extends React.Component {
constructor(props) {
console.log("constructor");
super(props);
this.state = { contador: 1 };
}
componentDidMount() {
console.log("ComponentDidMount");
}
componentDidUpdate() {
console.log("componentDidUpdate");
}
componentWillUnmount() {}
incrementa() {
this.setState({ contador: ++this.state.contador });
}
render() {
return (
<div>
<h1> teste de eventos </h1>
<button onClick={() => this.incrementa()}>
{this.state.contador}
</button>
</div>
);
}
}
ReactDOM.render(<Contador />, document.getElementById("teste"));
O método componentDidMount()
é executado depois que o componente é renderizado no DOM.
O método componentWillUnmount()
é executado sempre que o componente for removido.
Manipular eventos em elementos React é muito semelhante a manipular eventos em elementos do DOM. Existem algumas diferenças de sintaxe:
Então na função render() programamos o evento assim:
render() {
return (
<button onClick={()=>this.incrementaContador()}>
{this.state.contador}
</button>
);
}
a função de callback que será chamada quando o evento ocorrer será incrementaContador()
:
incrementaContador() {
this.setState({ contador: ++this.state.contador })
}
Observe como alteramos o valor de contador através da chamada da função setState()
.
O código final fica assim:
class Contador extends React.Component {
constructor(props) {
super(props);
this.state = { contador: 1 };
}
incrementaContador() {
this.setState({ contador: ++this.state.contador })
}
render() {
return (
<button onClick={()=>this.incrementaContador()}>
{this.state.contador}
</button>
);
}
}
ReactDOM.render(<Contador />, document.getElementById("root"));
Em HTML, elementos de formulário como <input>, <textarea> e <select> normalmente mantêm seu próprio estado e o atualiza baseado na entrada do usuário. Em React, o estado mutável é normalmente mantido na propriedade state dos componentes e atualizado apenas com setState().
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = { value: "" };
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
alert("Um nome foi enviado: " + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={(e) => this.handleSubmit(e)}>
<label>
Nome:
<input
type="text"
value={this.state.value}
onChange={(e) => this.handleChange(e)}
/>
</label>
<input type="submit" value="Enviar" />
</form>
);
}
}
ReactDOM.render(<NameForm />, document.getElementById("root"));
Hooks foram introduzidos em 2018 no React 16.8. Eles permitem que você use o state e outros recursos sem escrever uma classe.
Hooks são funções que permitem acesso aos recursos de state e ciclo de vida do React a partir de componentes funcionais, ou seja, escritos como funções e não como classes. Hooks não funcionam dentro de classes — eles permitem que você use React sem classes.
Para usar hooks você deve importar assim:
import React, { useEffect, useState } from 'react';
Exemplo de utilização de efeitos colaterais
import React, { useState, useEffect } from 'react';
function Exemplo() {
const [count, setCount] = useState(0);
// Similar ao componentDidMount e componentDidUpdate:
useEffect(() => {
// Atualiza o titulo do documento usando a API do browser
document.title = `Você clicou ${count} vezes`;
});
return (
<div>
<p>Você clicou {count} vezes</p>
<button onClick={() => setCount(count + 1)}>
Clique aqui
</button>
</div>
);
}
Para criar a aplicação:
npx create-react-app crud
Para importar o Boostrap:
C:\React\crud>npm install react-bootstrap bootstrap
Adicione a seguinte linha no topo de seu arquivo index.js
import 'bootstrap/dist/css/bootstrap.min.css';
Em sua pasta src, crie uma nova pasta chamada componentes
. Esta pasta conterá todos os nossos componentes React. Na nova pasta, crie dois arquivos intitulados hoct.js
e ListaProdutos.js
.
Esses dois arquivos conterão os componentes que serão necessários em nosso aplicativo. O arquivo ListaProdutos.js
tratará da exibição do resultado da consulta à API, e o arquivo hoc.js
conterá um componente de ordem superior que exibirá uma mensagem enquanto a requisição HTTP que faremos ainda estiver em andamento. No arquivo ListaProdutos.js
que criamos dentro da pasta de componentes, vamos colar o seguinte código:
import React from 'react';
const ListaProdutos = (props) => {
const { produtos } = props;
if (!produtos || produtos.length === 0) return <p>Carregando ...</p>;
return (
<TabelaDeProdutos listaDeProdutos={produtos}/>
);
};
class Linha extends React.Component {
render() {
const produto = this.props.produto;
return (
<tr>
<td>{produto.id}</td>
<td>{produto.name}</td>
<td>{produto.description}</td>
<td>{produto.price}</td>
<td>{produto.imgUrl}</td>
</tr>
);
}
}
class TabelaDeProdutos extends React.Component {
render() {
const linhas = [];
this.props.listaDeProdutos.forEach(
(produto) => {
linhas.push(
<Linha produto={produto} />
);
}
);
return (
<table className="table">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Descrição</th>
<th>Preço</th>
<th>Imagem</th>
</tr>
</thead>
<tbody>{linhas}</tbody>
</table>
);
}
}
export default ListaProdutos;
No arquivo hoc.js
que criamos dentro da pasta de componentes, vamos colar o seguinte código:
import React from 'react';
function hoc(Component) {
return function CarregandoProdutos({ isLoading, ...props }) {
if (!isLoading) return <Component {...props} />;
return (
<p style={{ textAlign: 'center', fontSize: '30px' }}>
Carregando dados
</p>
);
};
}
export default hoc;
No seu arquivo App.js dentro da pasta src, vamos colar o seguinte código:
import React, { useEffect, useState } from 'react';
import './App.css';
import ListaProdutos from './componentes/ListaProdutos';
import hoc from './componentes/hoc';
function App() {
const CarregandoProdutos = hoc(ListaProdutos);
const [estadoDaAplicacao, setEstadoDaAplicacao] = useState({
consultando: false,
produtos: null,
});
useEffect(() => {
setEstadoDaAplicacao({ consultando: true });
const apiUrl = `https://projeto-integrador-4.herokuapp.com/products`;
fetch(apiUrl)
.then((res) => res.json())
.then((repos) => {
setEstadoDaAplicacao({ consultando: false, produtos: repos.content });
});
}, [setEstadoDaAplicacao]);
return (
<div className='App'>
<CarregandoProdutos isLoading={estadoDaAplicacao.consultando} produtos={estadoDaAplicacao.produtos} />
</div>
);
}
export default App;
Nosso App.js é um componente funcional que usa React Hooks para lidar com o estado e também os efeitos colaterais.
Clique no ícone de debug. Uma pasta .vscode será criada na raiz do seu projeto |
Aperte o botão verde no painel de debug. Launch Chrome against localhost |
Renderização condicional em React funciona da mesma forma que condicionais funcionam em JavaScript.
Operadores JavaScript como if
ou o operador condicional ternário (expressão condicional ? expr1 : expr2 ) podem ser usados para criar elementos representando estados.
Elementos React podem ser armazenados em variáveis, pois naturalmente Javascript permite armazenar tanto valores quanto funções.
var ola = <H1>Olá Mundo!</H1>;
Em JavaScript, expressões como (true && expressão) são sempre avaliadas como verdade e (false && expressão) são sempre avaliadas como false.
Portanto, se a condição é true, o elemento logo depois do && irá aparecer no resultado. Se o elemento é false, React irá ignora-lo.
Outro método para renderizar elementos inline é utilizar o operador condicional em JavaScript condição ? true : false.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(
(number) =><li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
O código acima mostra uma lista não ordenada na tela
Porém o console mostra um erro:
‘key' é um atributo especial que você precisa definir ao criar listas de elementos. Iremos analisar os motivos pelos quais isso é importante na próxima seção.
Este atributo deve ser um valor do string único para cada elemento da lista. Assim, o código pode se corrigido:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(
(number) =><li key={number.toString()}>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
Quando não temos nenhum valor único para os itens renderizados, podemos usar o índice do item como chave em último recurso. Observer que foi adicionado um segundo parâmetro aos parâmetros da função chamada dentro de map:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map(
(number,index) =><li key={index}>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
Visão geral da estrutura da aplicação
A aplicação é um sistema de cadastro de livros de uma biblioteca e o cliente React consome uma api Rest CRUD implementada por um servidor Spring Boot.
é um contêiner com React Router. Exibe uma barra de navegação com links para as rotas definidas pelos componentes <Switch> e <Route>.
exibe todos os livros
é um formulário para criar um novo livro.
é um formulário para editar um livro.Esses componentes chamam métodos de serviço, definidos no arquivo /services/Endpoints.js
, que usam axios para fazer requisições HTTP e receber respostas.
npx create-react-app aula-react-crud
Neste projeto vamos utilizar três dependências:
yarn add bootstrap react-router-dom axios
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root")
);
import React from "react";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import ListagemLivros from "./components/ListagemLivros.js";
import NovoLivro from "./components/NovoLivro.js";
import EditaLivro from "./components/EditaLivro.js";
function App() {
return (
<BrowserRouter>
<nav className="container navbar navbar-expand navbar-dark bg-dark">
<h1 className="navbar-brand">Exemplo CRUD</h1>
<div className="navbar-nav mr-auto">
<li className="nav-item">
<Link to="/livros" className="nav-link">
Livros
</Link>
</li>
<li className="nav-item">
<Link to="/novo" className="nav-link">
Novo livro
</Link>
</li>
</div>
</nav>
<div className="container mt-3">
<Routes>
<Route path="/" element={<ListagemLivros />} />
<Route path="novo" element={<NovoLivro />} />
<Route path="livros/:id" element={<EditaLivro />} />
<Route path="livros" element={<ListagemLivros />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
import axios from "axios";
const httpClient = axios.create({
baseURL: "http://localhost:8080/api",
headers: {
"Content-type": "application/json"
}
})
export const getAll = () => {
return httpClient.get("/livro");
};
export const get = id => {
return httpClient.get(`/livro/${id}`);
};
export const create = data => {
return httpClient.post("/livro", data);
};
export const update = (id, data) => {
return httpClient.put(`/livro/${id}`, data);
};
export const remove = id => {
return httpClient.delete(`/livro/${id}`);
};
import React, { useState, useEffect } from "react";
import * as api from "../services/Endpoints"
import { Link } from "react-router-dom";
const ListagemLivros = () => {
const [livros, setLivros] = useState([]);
const [livroSelecionado, setLivroSelecionado] = useState(null);
const [currentIndex, setCurrentIndex] = useState(-1);
useEffect(() => {
buscaLivros();
}, []);
const buscaLivros = () => {
api.getAll()
.then(response => {
setLivros(response.data);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
};
const setLivroAtivo = (livro, index) => {
setLivroSelecionado(livro);
setCurrentIndex(index);
};
return (
<div className="container list row">
<div className="col-md-6">
<h4>Livros</h4>
<ul className="list-group py-1">
{livros &&
livros.map((livro, index) => (
<li className={"list-group-item " + (index === currentIndex ? "active" : "")}
onClick={() => setLivroAtivo(livro, index)}
key={index}
>{livro.titulo}</li>
))}
</ul>
</div>
<div className="col-md-6">
{livroSelecionado ? (
<div>
<h4>Detalhe</h4>
<div>
<label>
<strong>Titulo:</strong>
</label>{" "}
{livroSelecionado.titulo}
</div>
<div>
<label>
<strong>Autor:</strong>
</label>{" "}
{livroSelecionado.autor}
</div>
<Link to={"/livros/" + livroSelecionado.id} className="btn btn-warning">Editar</Link>
</div>
) : (
<div>
<br />
<p>Escolha um livro ...</p>
</div>
)}
</div>
</div>
);
};
export default ListagemLivros;
import React, { useState } from "react";
import * as api from "../services/Endpoints"
const NovoLivro = () => {
const estadoInicialLivro = {
id: null,
titulo: "",
autor: "",
};
const [livro, setLivro] = useState(estadoInicialLivro);
const [submitted, setSubmitted] = useState(false);
const trataCampo = (event) => {
const { name, value } = event.target;
setLivro({ ...livro, [name]: value });
};
const novo = () => {
setLivro(estadoInicialLivro);
setSubmitted(false);
};
const enviarLivro = () => {
var data = {
titulo: livro.titulo,
autor: livro.autor
};
console.log(data)
api.create(data)
.then(response => {
setLivro({
id: response.data.id,
titulo: response.data.titulo,
autor: response.data.autor,
});
setSubmitted(true);
console.log(response.data);
})
.catch(e => { console.log(e); });
};
return (
<div className="submit-form">
{submitted ? (
<div>
<h4>Livro cadastrado com sucesso!</h4>
<button className="btn btn-success" onClick={novo}>Novo</button>
</div>
) : (
<div>
<div className="form-group">
<label htmlFor="titulo">Titulo</label>
<input
type="text"
className="form-control"
id="titulo"
required
value={livro.titulo}
onChange={trataCampo}
name="titulo"
/>
</div>
<div className="form-group mt-4">
<label htmlFor="description">Autor</label>
<input
type="text"
className="form-control"
id="autor"
required
value={livro.autor}
onChange={trataCampo}
name="autor"
/>
</div>
<button onClick={enviarLivro} className="btn btn-success mt-4">Cadastrar</button>
</div>
)}
</div>
);
}
export default NovoLivro;
import React, { useState, useEffect } from "react";
import * as api from "../services/Endpoints"
const EditaLivro = props => {
const estadoInicial = {
id: null,
titulo: "",
autor: "",
};
const [livro, setLivro] = useState(estadoInicial);
const [message, setMessage] = useState("");
const getLivro = (id) => {
api.get(id)
.then(response => {
setLivro(response.data);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
getLivro(props.match.params.id);
}, [props.match.params.id]);
const trataCampo = event => {
const { name, value } = event.target;
setLivro({ ...livro, [name]: value });
};
const atualizarLivro = () => {
api.update(livro.id, livro)
.then(response => {
console.log(response.data);
setMessage("Livro atualizado!");
})
.catch(e => { console.log(e); });
};
const excluirLivro = () => {
api.remove(livro.id)
.then(response => {
console.log(response.data);
props.history.push("/livros");
})
.catch(e => { console.log(e); });
};
return (
<div>
{livro ? (
<div className="edit-form">
<h4>Livro</h4>
<form>
<div className="form-group">
<label htmlFor="titulo">Titulo</label>
<input
type="text"
className="form-control"
id="titulo"
name="titulo"
value={livro.titulo}
onChange={trataCampo}
/>
</div>
<div className="form-group mt-3">
<label htmlFor="description">Autor</label>
<input
type="text"
className="form-control"
id="autor"
name="autor"
value={livro.autor}
onChange={trataCampo}
/>
</div>
</form>
<button className="btn btn-warning danger mt-3" onClick={excluirLivro}>Excluir</button>
<button type="submit" className="btn btn-success mt-3 mx-3" onClick={atualizarLivro}>
Atualizar
</button>
<p>{message}</p>
</div>
) : (
<div>
<br />
<p>Selecione um livro ...</p>
</div>
)}
</div>
);
};
export default EditaLivro;