Acesse os slides remotamente em:
Acesse os slides e os códigos das demonstrações localmente clonando o repositório:
$ git clone --recursive git@github.com:vcampitelli/slides-sites-reativos-javascript.git
github.com/vcampitelli/slides-sites-reativos-javascript
A ideia dessa palestra é despertar a curiosidade! Em cenários reais, utilize bibliotecas robustas, como React, Svelte, Vue.js ou Angular.
Também existem outras alternativas, como SolidJS, Preact (compatível com React) ou até mesmo htmx.
<html>
<body>
<div id="header">
<!-- ... -->
<a href="/pagina">Link</a>
</div>
<iframe src="body.php?page=<?= $_GET['page'] ?>" name="centro"></iframe>
<div id="footer">
<!-- ... -->
</div>
</body>
</html>
Além de Dojo, Backbone, MooTools, a primeira versão do AngularJS...
$(document).ready(function() {
$.ajax({
url: '/posts/1',
method: 'GET',
success: function (post) {
$('#loading').fadeOut();
$('#content')
.html('' + post.title + '
' + post.body + '
')
.fadeIn();
},
error: function() {
$('#loading').fadeOut();
$('#content').html('Erro ao carregar os dados').fadeIn();
}
});
});
A Complete History of JavaScript Frameworks in the Modern Age, from the Perspective of a Confused Backend Developer
Exemplo de código em React
export default function MyApp() {
return (
<div>
<h1>Bem-vindo ao meu aplicativo</h1>
<Componente />
</div>
);
}
Exemplo de código em Vue
<div id="app">
<button @click="count++">
Count is: {{ count }}
</button>
</div>
JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside a JavaScript file.Documentação do React
Código em JSX
import { useState } from 'react';
export default function Componente() {
const [count, setCount] = useState(0);
return (
<div>
<p>Você clicou {count} vezes</p>
<button
type="button"
onClick={() => setCount(count + 1)}>
Incrementar
</button>
</div>
);
}
Código transpilado em JavaScript
import { useState } from 'react';
export default function Componente () {
const [count, setCount] = useState(0);
return React.createElement(
'div', null,
React.createElement(
'p', null,
'Voc\xEA clicou ', count, ' vezes'
),
React.createElement(
'button',
{
type: 'button',
onClick: () => setCount(count + 1),
},
'Incrementar',
)
);
}
O virtual DOM (VDOM) é um conceito de programação onde uma representação ideal, ou “virtual”, da interface do usuário é mantida em memória e sincronizada com o DOM “real” por uma biblioteca como o ReactDOM.Documentação do React
São recursos que permitem que você gerencie o estado, ciclos de vida do componente e outros recursos do React sem precisar escrever componentes em forma de classes.Blog da Trybe
Interpolar expressões, estruturas condicionais e de repetição são difíceis
const $ul = document.createElement('ul');
for (const item of items) {
const $li = document.createElement('li');
$li.id = `item-${item.id}`;
$li.innerText = item.nome;
$ul.appendChild($li);
}
document.body.appendChild($ul);
Criação do JSX
para facilitar o manuseio de elementos
return (
<ul>
{itens.map((item) => (
<li id={`item-${item.id}`}>
{item.nome}
</li>
)}
</ul>
);
Recarregar componentes quando algum valor é alterado ou precisa ser recomputado
<div>
<p>
Você clicou <span id="count">0</span> vezes
</p>
<button type="button" id="btn-click">
Incrementar
</button>
</div>
let count = 0;
const $count = document.getElementById('count');
const $button = document.getElementById('btn-click');
$button.onclick = function () {
$count.innerText = ++count;
};
Funcionalidade useState()
que retorna um array com dois elementos: o
valor atual e um método de mutação
import { useState } from 'react';
export default function Componente() {
const [count, setCount] = useState(0);
return (
<div>
<p>Você clicou {count} vezes</p>
<button
type="button"
onClick={() => setCount(count + 1)}>
Incrementar
</button>
</div>
);
}
Fluxo para exibir um texto "Carregando" enquanto realiza uma operação assíncrona
<div id="loading">Carregando...<div>
<div id="body" style="display: none"><div>
const $body = document.getElementById('body');
fetch('/posts')
.then(r => r.json())
.then((data) => {
$body.innerText = `${data.id} ${data.name}`;
$loading.style.display = 'none';
$body.style.display = 'block';
});
Hook useEffect()
que executa uma função ao carregar o componente
pela primeira vez
import { useEffect, useState } from 'react';
export default function Componente() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/posts')
.then(r => r.json())
.then(setData);
}, []);
if (data === null) {
return (
<div>Carregando...</div>
);
}
return (
<div>{data.id} {data.name}</div>
);
}
Executar uma função sempre que determinados valores forem alterados
<select>
<!-- Options... -->
<select>
<div id="loading">Carregando...<div>
<div id="body" style="display: none"><div>
const $loading = document.getElementById('loading');
const $select = document.getElementById('select');
const $body = document.getElementById('body');
$select.onchange = function (e) {
const postId = e.target.value;
$loading.style.display = 'block';
fetch(`/posts/${postId}`)
.then(r => r.json())
.then((post) => {
$body.innerText = post.contents;
})
.finally(() => {
$loading.style.display = 'none';
});
};
Hook useEffect()
com um array de dependências para
executar a função
import { useEffect, useState } from 'react';
export default function Componente() {
const [postId, setPostId] = useState(null);
const [data, setData] = useState(null);
useEffect(() => {
if (!postId) return;
setData(null);
fetch(`/posts/${id}`)
.then(r => r.json())
.then(setData);
}, [postId]);
const $select = (
<select onChange={(e) => {
setPostId(e.target.value);
}}>
{/* Options... */}
<select>
);
if (data === null) {
return (
<>
{$select}
<div>Carregando...</div>
</>
);
}
return (
<>
{$select}
<div>{data.contents}</div>
</>
);
}
import { getCurrentTheme } from '@/preferences';
document.body.classList.add(
getCurrentTheme()
);
import { setCurrentTheme } from '@/preferences';
setCurrentTheme('dark');
document.location.reload(true);
// ou algo como:
reloadTheme();
Hooks createContext
e useContext
para criação e uso
de informações
import { createContext } from 'react';
export const ThemeContext = createContext(null);
export default function Theme() {
return (
<ThemeContext.Provider value="light">
<App />
</ThemeContext.Provider>
);
}
import { useContext } from 'react';
import ThemeContext from '@/providers/ThemeContext';
export default function App() {
const theme = useContext(ThemeContext);
return (
<body className={theme}>
{/* ... */}
</body>
);
}