O que é ?
ES6
Declarativo
One-way data flow (Fluxo de dados unidirecional)
Focado em composição, não herança
Virtual DOM
JSX
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
Componentes
React Componente:
Componente Exemplo1.js
import React, { Component } from 'react';
import logo from './logo.svg';
import '../App.css';
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
</header>
</div>
);
}
}
Componente
export default class Propriedade extends Component {
campo = 10;
constructor(props) {
super(props);
this.state = { texto: "Classe Propriedade" };
}
.....
props são recebidas por propriedades da tag na sua declaração e não podem ser alteradas pelo componente:
<Propriedade nome="João do Exemplo" />
equivale
this.props.nome="João do Exemplo";
render() - Método obrigatório, retorna a renderização do componente baseado em suas propriedades e estado JSX JSX é um "açúcar sintático", ele torna possível escrever
código em notação XML dentro de código JavaScript
let elem = <div>
<p>Welcome to TutsPlus</p>
</div>;
É equivalente:
let elem = React.createElement(
"div",
null,
React.createElement(
"p",
null,
"Welcome to TutsPlus"
)
);
)
JSX REACT e JSX suportam todas as tags HTML5 nativas, não sendo necessário importa-lás
a, abbr, address, area, article, aside, audio, b, base, bdi, bdo,
big, body, br, button, canvas, caption, cite, code, col, colgroup,
data, datalist, dd, del, details, dfn, dialog, div, dl, dt, em,
embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4,
h5, h6, head, header, hgroup, hr, html, i, iframe, img, input, ins,
kbd, keygen, label, legend, li, link, main, map, mark, menu,
menuitem, meta, meter, nav, noscript, object, ol, optgroup, option,
output, p, param, picture, pre, progress, q, rp, rt, ruby, s, samp,
script, section, select, small, source, span, strong, style, sub,
summary, sup, table, tbody, td, textarea, tfoot, th, thead, time,
title, tr, track, u, ul, var, video, wbr, circle, clipPath, defs,
ellipse, g, image, line, linearGradient, mask, path, pattern,
polygon, polyline, radialGradient, rect, stop, svg, text, tspa
JSX Através das chaves ({}) é possível acessar atributos, variáveis, executar expressões e comandos no JSX
class Exemplo extends Component {
a =10;
render() {
let b=2;
return <div>
soma de {this.a} + {b} =<span>{this.a+b}</span>
</div>;
}
}
Resulta em:
soma de 10 + 2 =12
Como regra geral, os atributos são escritos no estilo camelCase, usando como separador de palavras uma letra maiúscula.
tabindex => tabIndex
colspan => colSpan
JSX O atributo style tem um tratamento especial no JSX, permitindo definir estilos "inline", através de um objeto
let estilos = {
color:'red',
backgroundColor:'blue',
fontWeight:'bold'
};
JSX O atributo style tem um tratamento especial no JSX, permitindo definir estilos "inline", através de um objeto
let estilos = {
color:'red',
backgroundColor:'blue',
fontWeight:'bold'
};
Ou
let elemento = <div style={{
color:'red',
backgroundColor:'black',
fontWeight:'bold'
}}>teste</div>;
JSX Os atributos do estilo utilizam a nomenclatura do DOM javaScript, que também é escrito no estilo camelCase
state Representa o estado interno de um componente react, não sendo visível para outros componentes.
state
export default class ExemploEstado extends Component {
constructor() {
super();
this.state = { contador: 1 }; // inicializa o estado
this.iniciaContagem();
}
iniciaContagem() {
let funcao = () => this.setState({
contador: this.state.contador + 1
// define um novo estado a partir do estado anterior
});
setInterval(funcao, 1000);
// executa a função a cada 1000 milesegundos (1 segundo)
}
render() {
return <div>Contagem:{this.state.contador}</div>
// renderiza o componente a partir do estado
}
}
state Ele não substitui o estado anterior pelo estado novo, mas funde os dois estados em um novo.
export default class ExemploEstado2 extends Component {
constructor() {
super();
this.state = {
nome: "João do Exemplo",
email: "joao@exemplo.com"
}; // inicializa o estado
setTimeout(() => {
this.setState({
email: "joao@gmail.com"
// Vai gerar um novo estado:
//{ nome: "João do Exemplo", email:"joao@gmail.com" }
})
}, 1000);
}
...
state setState é assíncrono, não há garantia de que o estado mude logo após sua chamada
export default class ExemploEstado3 extends Component {
constructor() {
super();
this.state = { contador: 1 }; // inicializa o estado
setTimeout(()=>this.incrementa(),1000);
}
incrementa() {
this.setState({
contador: this.state.contador + 1
});
console.log(this.state.contador);
// pode gerar 1 ou 2
}
}
state É possivel passar uma função que é chamada após o estado ser atualizado setState(estado, funcao)
export default class ExemploEstado3 extends Component {
constructor() {
super();
this.state = { contador: 1 }; // inicializa o estado
setTimeout(()=>this.incrementa(),1000);
}
incrementa() {
this.setState({
contador: this.state.contador + 1
}, ()=> {
console.log(this.state.contador);
// vai imprimir 2
} );
}
}
state É possível passar uma função como estado. Ela recebe o estado anterior como paramêtro e retorna o novo estado
export default class ExemploEstado5 extends Component {
constructor() {
super();
this.state = { contador: 1 }; // inicializa o estado
setTimeout(()=>this.incrementa3(),1000);
}
incrementa3() {
this.setState((estadoAnterior) => {
return { contador: estadoAnterior.contador + 1 }
});
this.setState((estadoAnterior) => {
return { contador: estadoAnterior.contador + 1 }
});
this.setState((estadoAnterior) => {
return { contador: estadoAnterior.contador + 1 }
});
// sempre vai gerar 4
}
}
incrementa() {
this.setState((estadoAnterior, props) => {
return { contador: estadoAnterior.contador + props.salto}
});
}
}
}
Componente pai envia uma função como paramêtro para componente filho
Quando o componente filho muda seu estado, ele notifica o pai chamando a função, passando como paramêtro o estado
eventos
export default class Contagem extends Component {
constructor() {
super();
this.state = { contador: 1, terminou: false };
setInterval(() => this.incrementa(), 1000);
}
incrementa() {
if (this.state.contador == this.props.limite) {
this.setState({chegou: true },
()=>{this.props.chegou(this.state.chegou)});
} else {
this.setState((estadoAnterior, props) => {
return { contador: estadoAnterior.contador+1}
});
}
}
render() {
return <div>Contagem:{this.state.contador}</div>
}
}
eventos
export default class ExemploEvento extends Component {
constructor() {
super();
this.state= { chegouExemplo:false };
}
render() {
if(this.state.chegouExemplo)
return <div>
Finalizada a contagem:
<button onClick={()=>this.setState({chegouExemplo:false})}>
Reiniciar</button>
</div>;
else
return <Contagem limite={10}
chegou={(valor)=>this.setState({chegouExemplo:valor})} />;
}
}
https://reactjs.org/docs/events.html Campos de entrada Campos de entrada nativos do HTML: <input>, <textarea>, <select>, ... possuem um estado interno que não é
controlado pelo react.
Para evitar conflitos e produzir uma "única fonte de verdade" o react propõem que um componente pai gerencie este estado. Estes elementos são denominados componentes
controlados.
Campos de entrada
export default class ExemploComponenteControlado extends Component {
constructor() {
super();
this.state = { valor:"" };
}
setValor(valor) {
this.setState({
valor:valor
});
}
render() {
return <div>
<label>Valor:</label>
<input value={this.state.valor}
onChange={(evento)=>this.setValor(evento.target.value)} />
Valor digitado({this.state.valor.length}):
{this.state.valor}
</div>
}
}
Campos de entrada O input checkbox html utiliza o atributo checked para definir seu estado
export default class ExemploCheckBox extends Component {
....
render() {
return <span>
<input
id="memorizar"
type="checkbox"
checked={this.state.memorizar}
onChange={(evento) =>
this.setMemorizar(evento.target.checked)} />
<label htmlFor="memorizar" >Memorizar senha</label>
</span>
}
}
Campos de entrada Campos do HTML 5 podem ter variação do valor real e o que é exibido
export default class ExemploInputHTML5 extends Component {
....
render() {
return <div><h2>HTML 5</h2>
<label> type="color" =></label>
<input type="color" value={this.state.color}
onChange={(evento) => this.setValor("color", evento.target.value)} />
Valor real:{this.state.color}<br /><br />
Formulário
export default class ExemploFormulario extends Component {
....
render() {
return <form onSubmit={(evento) => {
// Previne que o formulário faça o submit
// trata o envio pelo método enviar
evento.preventDefault(); this.enviar() }}
style={{
border: "1px solid black",
padding: "10px"
}}
>
<label>Nome:</label>
<input type="text" value={this.state.nome} required
onChange={(evento) => this.setValor("nome", evento.target.value)} />
<br /><br />
<label>Sexo:</label>
<select value={this.state.sexo} required
onChange={(evento) => this.setValor("sexo", evento.target.value)}>
<option value=""></option>
<option value="masculino">Masculino</option>
<option value="feminino">Feminino</option>
</select><br /><br />
<label>Nascimento:</label>
<input type="date" value={this.state.nascimento}
onChange={(evento) => this.setValor("nascimento", evento.target.value)} />
<br /><br />
<label>E-mail:</label>
<input type="email" value={this.state.email} required
onChange={(evento) => this.setValor("email", evento.target.value)} />
<br /><br />
<input
id="notificacao"
type="checkbox"
checked={this.state.notificacao}
onChange={(evento) => this.setValor("notificacao", evento.target.checked)} />
<label htmlFor="notificacao" >Receber notificação por e-mail </label>
<br /><br />
<button type="submit">Cadastar</button>
</form>
}
Formulário
export default class ExemploFormulario extends Component {
....
// função genérica para atribuir valores do estado
setValor(campo, valor) {
this.setState(
(estadoAntigo) => {
estadoAntigo[campo] = valor;
return estadoAntigo;
});
}
Formulário
export default class ExemploFormulario extends Component {
....
// função que notifica o componente pai
// através da callback cadastrar
enviar() {
let cadastro = {
nome: this.state.nome,
sexo: this.state.sexo,
nascimento: this.state.nascimento,
email: this.state.email,
notificacao: this.state.notificacao
};
this.props.cadastrar(cadastro);
}
Listas / arrays Para converter arrays em tags no JSX, normalmente é empregada a função map
array.map(( elem, index, array ) => {
...
// deve retornar o novo item do array na posição
});
map() percorre o array da esquerda para a direita invocando a função de retorno em cada elemento. Para cada chamada de retorno, o valor devolvido se torna o elemento do
novo array. Depois que todos os elementos foram percorridos, map() retorna o novo array com todos os elementos "traduzidos". Listas / arrays
let a=[1,2,3,4,5];
let b=a.map((valor) =>{return valor*2});// b= [2, 4, 6, 8, 10]
let c=a.map((valor, indice) =>{return "pos:"+indice+"="+valor});
// c= ["pos:0=1", "pos:1=2", "pos:2=3", "pos:3=4", "pos:4=5"]
let d=a.map((valor, indice) =>{return <li>{indice} - {valor}</li>});
//[<li>0 - 1</li>, <li>1 - 2</li>, <li>2 - 3</li>
//, <li>3 - 4</li>, <li>4 - 5</li>]
Listas / arrays
export default class ExemploLista extends Component {
constructor() {
super();
this.state = {
meses:["janeiro", "fevereiro", "março", "abril", "maio", "junho",
"julho", "agosto", "setembro", "outubro", "novembro", "dezembro"]
};
}
render() {
return (
<ul>
{this.state.meses.map((mes) => { return <li>{mes}</li> })}
</ul>
);
}
}
Listas / arrays
export default class ExemploLista extends Component {
constructor() {
super();
this.state = {
meses: ["janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"]
};
}
render() {
let lista = [];
for (let x = 0; x < this.state.meses.length; x++) {
let mes = <li>{this.state.meses[x]}</li>;
lista.push(mes);
}
return (
<ul>
{lista}
</ul>
);
}
}
Listas / arrays
export default class ExemploLista extends Component {
constructor() {
super();
this.state = {
meses:["janeiro", "fevereiro", "março", "abril", "maio", "junho",
"julho", "agosto", "setembro", "outubro", "novembro", "dezembro"]
};
}
render() {
return (
<ul>
{this.state.meses.map((mes) => <li>{mes}</li>)}
</ul>
);
}
}
Listas / arrays
export default class ExemploLista2 extends Component {
constructor() {
super();
this.state = { contatos: [
{id:1, nome:"João do Exemplo", email:"joao@exemplo.com"},
{id:2, nome:"Maria do Exemplo", email:"maria@exemplo.com"},
{id:3, nome:"Enzo do Exemplo", email:"enzo@exemplo.com"}
]};
}
render() {
return (<table>
<tr><th>Nome</th><th>E-mail</th></tr>
{this.state.contatos.map((contato) =>
<tr key={contato.id}>
<td>{contato.nome}</td>
<td>{contato.email}</td>
</tr>)}
</table>
);
}
}
Listas / arrays Keys ajudam o React a identificar qual elemento foi adicionado/removido de uma lista/array. Uma Key deve sempre ser um valor único entre todos os possíveis
elementos da lista. Ciclo de vida Métodos que serão executados em determinados momentos da vida de um componente.
Dividido em 3 fases:
Criação
Atualizações
Destruição
Ciclo de vida
export default class ExemploEstado extends Component {
constructor() {
super();
this.state = {
contador: 1
};
}
componentDidMount() {
let funcao = () => this.setState({
contador: this.state.contador + 1
});
this.interval = setInterval(funcao, 1000);
componentWillUnmount() {
clearInterval(this.interval);
}
Ciclo de vida
export default class ExemploErroDiv extends Component {
render() {
return <div>{this.state.naoTem}</div>
}
}
export default class ExemploErro extends Component {
....
componentDidCatch(erro, info) {
this.setState({erro:erro,info:info });
}
render() {
if (this.state.erro) {
return <h1>Erro:{this.state.erro.toString()} </h1>;
} else {
return <div> Contagem:
{this.state.contador<5?this.state.contador:<ExemploErroDiv/>}
</div>
}
}
Ciclo de vida
export default class ExemploFormulario extends Component {
constructor() {
super();
this.state = {
nome: "", sexo: "", nascimento: "",
email: "", notificacao: ""
};}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.cadastro) {
return {
nome: nextProps.cadastro.nome,
sexo: nextProps.cadastro.sexo,
nascimento: nextProps.cadastro.nascimento,
email: nextProps.cadastro.email,
notificacao: nextProps.cadastro.notificacao
}
}
return null;
}