React 18 - Transitions
Marcus Vinicius
Posted on March 27, 2023
No React 18, foi introduzido um novo recurso chamado Transitions. Transitions é uma API que permite aos desenvolvedores gerenciar animações e transições durante as renderizações, de forma a evitar que o usuário perceba interrupções ou atrasos ao interagir com a interface.
As Transitions do React 18 ajudam a criar experiências de usuário mais suaves e responsivas, permitindo que os desenvolvedores controlem e priorizem a renderização de componentes e atualizações de estado. Isso é especialmente útil quando há muitas mudanças no DOM, como em casos de carregamento de dados, atualizações em tempo real ou animações complexas.
A API de Transitions introduz o hook useTransition, que pode ser usado para definir e controlar uma transição. O useTransition retorna um array com dois elementos: o primeiro é uma função que pode ser usada para iniciar uma transição, e o segundo é um booleano que indica se a transição está ativa ou não.
Aqui está um exemplo básico de como usar o useTransition:
import { useState, useTransition } from "react";
function App() {
const [data, setData] = useState(null);
const [startTransition, isPending] = useTransition();
const fetchData = async () => {
startTransition(() => {
setData(null);
});
const response = await fetch("/api/data");
const result = await response.json();
startTransition(() => {
setData(result);
});
};
return (
<div>
<button onClick={fetchData}>Carregar dados</button>
{isPending && <p>Carregando...</p>}
{data && <div>{JSON.stringify(data)}</div>}
</div>
);
}
Neste exemplo, a função fetchData é chamada quando o usuário clica no botão "Carregar dados". A transição é iniciada com a função startTransition e, enquanto a transição estiver ativa, o componente exibirá "Carregando...". Quando a transição terminar e os dados forem carregados, o componente exibirá os dados na tela.
As Transitions no React 18 permitem que os desenvolvedores criem experiências de usuário mais fluidas e otimizadas, oferecendo maior controle sobre o processo de renderização e atualização dos componentes.
Vamos criar um exemplo mais complexo usando Transitions no React 18 para gerenciar a exibição de uma lista de itens com animações de entrada e saída. Para isso, utilizaremos a biblioteca react-spring para criar as animações.
Criaremos o componente AnimatedList:
import { useState, useTransition } from "react";
import { useTransition as useSpringTransition, animated } from "react-spring";
function AnimatedList() {
const [items, setItems] = useState([]);
const [inputValue, setInputValue] = useState("");
const [startTransition, isPending] = useTransition();
const transitions = useSpringTransition(items, {
from: { opacity: 0, transform: "translate3d(0, -40px, 0)" },
enter: { opacity: 1, transform: "translate3d(0, 0, 0)" },
leave: { opacity: 0, transform: "translate3d(0, -40px, 0)" },
config: { duration: 300 },
});
const addItem = () => {
startTransition(() => {
setItems((prevItems) => [...prevItems, inputValue]);
setInputValue("");
});
};
const removeItem = (index) => {
startTransition(() => {
setItems((prevItems) => prevItems.filter((_, i) => i !== index));
});
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
disabled={isPending}
/>
<button onClick={addItem} disabled={isPending}>
Adicionar item
</button>
<ul>
{transitions((style, item, _, index) => (
<animated.li key={item} style={style} onClick={() => removeItem(index)}>
{item}
</animated.li>
))}
</ul>
</div>
);
}
export default AnimatedList;
Neste exemplo, criamos um componente AnimatedList que permite adicionar e remover itens com animações suaves de entrada e saída. A lista é gerenciada usando o estado items, e as transições são criadas usando a API useTransition do React 18 e a API useTransition do react-spring.
Ao clicar no botão "Adicionar item", a função addItem é chamada e inicia uma transição para adicionar o item à lista. Da mesma forma, ao clicar em um item da lista, a função removeItem é chamada para iniciar uma transição e remover o item. Enquanto a transição estiver ativa, o input e o botão são desabilitados para evitar interações adicionais.
As animações de entrada e saída são definidas no objeto de configuração passado para a função useSpringTransition. Neste caso, os itens da lista são animados com uma mudança de opacidade e uma transformação de posição no eixo Y.
Esse exemplo demonstra como combinar as Transitions do React 18 com animações CSS usando a biblioteca react-spring para criar experiências de usuário mais fluidas e interativas.
Vamos criar o mesmo exemplo usando a biblioteca framer-motion.
import { useState, useTransition } from "react";
import { AnimatePresence, motion } from "framer-motion";
function FramerMotionList() {
const [items, setItems] = useState([]);
const [inputValue, setInputValue] = useState("");
const [startTransition, isPending] = useTransition();
const addItem = () => {
startTransition(() => {
setItems((prevItems) => [...prevItems, inputValue]);
setInputValue("");
});
};
const removeItem = (index) => {
startTransition(() => {
setItems((prevItems) => prevItems.filter((_, i) => i !== index));
});
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
disabled={isPending}
/>
<button onClick={addItem} disabled={isPending}>
Adicionar item
</button>
<ul>
<AnimatePresence>
{items.map((item, index) => (
<motion.li
key={item}
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
onClick={() => removeItem(index)}
>
{item}
</motion.li>
))}
</AnimatePresence>
</ul>
</div>
);
}
export default FramerMotionList;
Neste exemplo, criamos um componente FramerMotionList que permite adicionar e remover itens com animações suaves de entrada e saída. A lista é gerenciada usando o estado items, e as transições são criadas usando a API useTransition do React 18 e a API AnimatePresence e motion do framer-motion.
Ao clicar no botão "Adicionar item", a função addItem é chamada e inicia uma transição para adicionar o item à lista. Da mesma forma, ao clicar em um item da lista, a função removeItem é chamada para iniciar uma transição e remover o item. Enquanto a transição estiver ativa, o input e o botão são desabilitados para evitar interações adicionais.
As animações de entrada e saída são definidas nos objetos initial, animate e exit dos componentes motion.li. Neste caso, os itens da lista são animados com uma mudança de opacidade e uma transformação de posição no eixo Y.
Esse exemplo demonstra como combinar as Transitions do React 18 com animações CSS usando a biblioteca framer-motion para criar experiências de usuário mais fluidas e interativas.
Posted on March 27, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.