Introdução ao React
O React é uma biblioteca JavaScript criada para construir interfaces de usuário (UI), especialmente em aplicações web de página única. Sua principal função é facilitar o desenvolvimento de interfaces dinâmicas e interativas, permitindo a criação de componentes reutilizáveis que otimizam a experiência do desenvolvedor e do usuário.
Linha do Tempo
- 2011: O React foi inicialmente criado por Jordan Walke, um engenheiro do Facebook. A motivação surgiu da necessidade de melhorar o desempenho e a experiência do usuário no feed de notícias da rede social.
- 2013: O React foi oficialmente lançado como um projeto open-source na conferência JSConf US. A primeira versão pública trouxe a abordagem de “renderização declarativa”, que se tornou um diferencial em relação a frameworks e bibliotecas existentes.
- 2015: O React Native foi introduzido, expandindo o uso da biblioteca para o desenvolvimento de aplicativos móveis, permitindo que o mesmo código JavaScript fosse usado para iOS e Android.
- 2016: O conceito de “hooks” foi introduzido no React 16.8, simplificando a manipulação de estado e ciclo de vida de componentes funcionais.
- 2020: React alcançou a versão 17, que focou em melhorias internas e atualizações progressivas, consolidando sua posição como uma das bibliotecas JavaScript mais populares do mundo.
Inventores
O React foi desenvolvido por Jordan Walke, que trabalhava no Facebook na época. Inspirado por tecnologias como XHP (uma biblioteca de PHP usada pelo Facebook), Walke queria criar uma solução que resolvesse problemas de re-renderização desnecessária e manutenção de grandes estados de interface. Seu trabalho foi aprimorado com a ajuda de uma equipe de engenheiros, incluindo Tom Occhino e Pete Hunt, que ajudaram a transformar o React no projeto open-source conhecido hoje.
Adoção
Desde seu lançamento, o React se tornou extremamente popular devido à sua abordagem inovadora e ao apoio contínuo do Facebook e da comunidade de código aberto. Empresas de diversos setores adotaram o React para criar interfaces de usuário modernas, eficientes e escaláveis. A biblioteca se destacou na construção de Single Page Applications (SPAs), onde a troca rápida de dados e a experiência do usuário são críticas.
Alguns dos fatores que contribuíram para sua ampla adoção incluem:
- Componentes Reutilizáveis: O React permite a criação de componentes encapsulados que podem ser reutilizados em diferentes partes da aplicação.
- Virtual DOM: O uso de um DOM virtual para renderizar alterações de forma otimizada garantiu maior desempenho, o que foi um diferencial competitivo.
- React Native: A possibilidade de desenvolver aplicativos móveis com o mesmo conjunto de ferramentas usadas para a web foi uma grande vantagem para empresas que queriam uma abordagem multiplataforma.
- Grande Comunidade e Ecossistema: O React tem uma comunidade ativa, com uma vasta gama de ferramentas, bibliotecas e frameworks associados, como Redux, React Router e Next.js.
Principais Empresas e Soluções Criadas com React
Várias grandes empresas utilizam o React em seus produtos e serviços devido à flexibilidade e ao desempenho que a biblioteca oferece:
- Facebook: Como desenvolvedor do React, o Facebook usa a biblioteca em partes importantes da sua interface, incluindo o feed de notícias e o Instagram, que também pertence à empresa.
- Instagram: Outro produto do Facebook, o Instagram foi um dos primeiros a adotar o React de forma significativa, especialmente em sua versão web, permitindo uma experiência de usuário mais rápida e eficiente.
- Airbnb: A plataforma de aluguel de imóveis adotou o React para criar sua interface web, permitindo um desenvolvimento mais rápido e eficiente. O React também foi utilizado em algumas partes do aplicativo móvel.
- Netflix: A gigante do streaming utiliza o React em várias partes da sua aplicação para melhorar a experiência de usuário, especialmente em dispositivos com limitações de hardware. O React permite uma atualização mais rápida de componentes da interface.
- WhatsApp: O aplicativo de mensagens usa o React para sua versão web, permitindo que os usuários aproveitem uma interface de usuário rica e responsiva.
- Dropbox: A interface do Dropbox foi reconstruída com React para proporcionar uma melhor experiência de usuário, com foco na eficiência e no desempenho.
- Salesforce: A Salesforce, empresa de CRM, utiliza o React em partes da sua plataforma Lightning, garantindo uma interface rápida e responsiva para os usuários corporativos.
- Uber: A Uber utiliza o React em várias partes do seu aplicativo de mapas e em interfaces que lidam com uma grande quantidade de dados de localização em tempo real.
- Shopify: A Shopify usa o React para seu painel de administração, oferecendo aos usuários uma interface moderna e interativa para gerenciar suas lojas online.
- Microsoft: O React é amplamente utilizado no Microsoft Office Online e no Outlook.com, otimizando a experiência dos usuários com componentes reutilizáveis e de alto desempenho.
Conclusão
O React se consolidou como uma das principais ferramentas para o desenvolvimento de interfaces de usuário modernas. Sua flexibilidade, eficiência e capacidade de ser usado tanto para aplicações web quanto móveis fazem dele uma escolha popular para empresas que buscam melhorar a experiência do usuário e otimizar o desenvolvimento de software. Com uma base sólida, grande comunidade e suporte contínuo, o React continuará a ser uma peça chave no ecossistema JavaScript para os próximos anos.
Aqui estão 50 exemplos de código cobrindo o aprendizado de React. Eles foram divididos em blocos de 10 exemplos cada.
Exemplos 1 a 10:
- Hello World com React
import React from 'react';
import ReactDOM from 'react-dom';
function App() {
return <h1>Hello, World!</h1>;
}
ReactDOM.render(<App />, document.getElementById('root'));
- Criando um Componente Simples
import React from 'react';
function Welcome(props) {
return <h1>Olá, {props.name}!</h1>;
}
export default Welcome;
- Renderizando Vários Componentes
import React from 'react';
function Welcome(props) {
return <h1>Bem-vindo, {props.name}!</h1>;
}
function App() {
return (
<div>
<Welcome name="João" />
<Welcome name="Maria" />
<Welcome name="Pedro" />
</div>
);
}
export default App;
- Estado Simples com
useState
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Você clicou {count} vezes</p>
<button onClick={() => setCount(count + 1)}>
Clique aqui
</button>
</div>
);
}
export default Counter;
- Evento de Clique
import React from 'react';
function Button() {
function handleClick() {
alert('Botão clicado!');
}
return <button onClick={handleClick}>Clique-me</button>;
}
export default Button;
- Passando Funções como Props
import React from 'react';
function Button({ onClick }) {
return <button onClick={onClick}>Clique-me</button>;
}
function App() {
function handleClick() {
alert('Botão clicado!');
}
return <Button onClick={handleClick} />;
}
export default App;
- Componente de Classe Simples
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Olá, {this.props.name}!</h1>;
}
}
export default Welcome;
- Ciclo de Vida com
componentDidMount
import React, { Component } from 'react';
class App extends Component {
componentDidMount() {
console.log('Componente montado!');
}
render() {
return <h1>Ver console para mensagem de montagem</h1>;
}
}
export default App;
- Condicionais no Render
import React from 'react';
function UserGreeting() {
return <h1>Bem-vindo de volta!</h1>;
}
function GuestGreeting() {
return <h1>Por favor, faça login.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
export default Greeting;
- Lista de Componentes com
map
import React from 'react';
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
);
return <ul>{listItems}</ul>;
}
function App() {
const numbers = [1, 2, 3, 4, 5];
return <NumberList numbers={numbers} />;
}
export default App;
Exemplos 11 a 20:
- Formulário Controlado
import React, { useState } from 'react';
function NameForm() {
const [name, setName] = useState('');
function handleChange(event) {
setName(event.target.value);
}
function handleSubmit(event) {
alert('Nome enviado: ' + name);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Nome:
<input type="text" value={name} onChange={handleChange} />
</label>
<button type="submit">Enviar</button>
</form>
);
}
export default NameForm;
- Estado Global com Context API
import React, { createContext, useState, useContext } from 'react';
const ThemeContext = createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Alternar Tema
</button>
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button>{theme} Theme</button>;
}
export default App;
- Consumindo uma API com
fetch
import React, { useState, useEffect } from 'react';
function DataFetching() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
}
export default DataFetching;
- Fragmentos para Evitar Elementos Extras
import React from 'react';
function FragmentDemo() {
return (
<>
<h1>Título</h1>
<p>Este é um parágrafo.</p>
</>
);
}
export default FragmentDemo;
- Renderização Condicional com
&&
import React from 'react';
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return <div className="warning">Atenção!</div>;
}
function App() {
const [showWarning, setShowWarning] = React.useState(true);
return (
<div>
<WarningBanner warn={showWarning} />
<button onClick={() => setShowWarning(!showWarning)}>
{showWarning ? 'Ocultar' : 'Mostrar'}
</button>
</div>
);
}
export default App;
- Renderização de Componentes Filhos
import React from 'react';
function FancyBorder(props) {
return <div className={'FancyBorder FancyBorder-' + props.color}>{props.children}</div>;
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">Bem-vindo</h1>
<p className="Dialog-message">Obrigado por visitar nosso site.</p>
</FancyBorder>
);
}
export default WelcomeDialog;
- Refs para Acessar o DOM
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focar no input</button>
</div>
);
}
export default TextInputWithFocusButton;
- Componente com
useEffect
import React, { useEffect, useState } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(seconds => seconds + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <div>Segundos: {seconds}</div>;
}
export default Timer;
- Renderização Condicional com
Ternário
import React, { useState } from 'react';
function LoginControl() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
{isLoggedIn ? <h1>Bem-vindo!</h1> : <h1>Por favor, faça login.</h1>}
<button onClick={() => set
IsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? 'Logout' : 'Login'}
</button>
</div>
);
}
export default LoginControl;
- Utilizando
PropTypespara Verificação de Props
import React from 'react';
import PropTypes from 'prop-types';
function Greeting({ name }) {
return <h1>Olá, {name}!</h1>;
}
Greeting.propTypes = {
name: PropTypes.string.isRequired,
};
export default Greeting;
Esses são os primeiros 20 exemplos. Nos próximos blocos, expandiremos para mais tópicos avançados em React!
Exemplos 21 a 30:
- Usando
useReducerpara Gerenciamento de Estado
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Contagem: {state.count}</p>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</div>
);
}
export default Counter;
- Renderização Condicional com
Switch
import React from 'react';
function Page(props) {
const page = props.page;
switch (page) {
case 'home':
return <h1>Home</h1>;
case 'about':
return <h1>Sobre</h1>;
case 'contact':
return <h1>Contato</h1>;
default:
return <h1>404 - Página não encontrada</h1>;
}
}
export default Page;
- Componente de Formulário com Vários Inputs
import React, { useState } from 'react';
function Form() {
const [inputs, setInputs] = useState({ username: '', email: '' });
function handleChange(event) {
const name = event.target.name;
const value = event.target.value;
setInputs({ ...inputs, [name]: value });
}
function handleSubmit(event) {
alert(`Username: ${inputs.username}, Email: ${inputs.email}`);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Username:
<input name="username" value={inputs.username} onChange={handleChange} />
</label>
<br />
<label>
Email:
<input name="email" value={inputs.email} onChange={handleChange} />
</label>
<br />
<button type="submit">Enviar</button>
</form>
);
}
export default Form;
- Passando Dados entre Componentes Irmãos
import React, { useState } from 'react';
function App() {
const [message, setMessage] = useState('');
return (
<div>
<Sibling1 setMessage={setMessage} />
<Sibling2 message={message} />
</div>
);
}
function Sibling1({ setMessage }) {
return (
<input
type="text"
onChange={(e) => setMessage(e.target.value)}
placeholder="Digite uma mensagem"
/>
);
}
function Sibling2({ message }) {
return <h2>Mensagem: {message}</h2>;
}
export default App;
- Renderização Baseada em Chave de Arrays
import React from 'react';
function List({ items }) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
function App() {
const fruits = ['Maçã', 'Banana', 'Laranja'];
return <List items={fruits} />;
}
export default App;
- Uso de
Memopara Otimização
import React, { useMemo } from 'react';
function ExpensiveComponent({ num }) {
const result = useMemo(() => {
console.log('Calculando...');
return num * 2;
}, [num]);
return <div>Resultado: {result}</div>;
}
function App() {
const [count, setCount] = React.useState(1);
return (
<div>
<ExpensiveComponent num={count} />
<button onClick={() => setCount(count + 1)}>Aumentar</button>
</div>
);
}
export default App;
- Componente Controlado vs. Não Controlado
import React, { useRef } from 'react';
function UncontrolledForm() {
const inputRef = useRef(null);
function handleSubmit(event) {
alert('Valor: ' + inputRef.current.value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Nome:
<input type="text" ref={inputRef} />
</label>
<button type="submit">Enviar</button>
</form>
);
}
export default UncontrolledForm;
- Componente Suspense e Lazy Loading
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Carregando...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
export default App;
- Implementando Higher-Order Components (HOCs)
import React from 'react';
function withLogger(WrappedComponent) {
return function Logger(props) {
console.log('Props: ', props);
return <WrappedComponent {...props} />;
};
}
function HelloWorld(props) {
return <h1>Olá, {props.name}!</h1>;
}
const HelloWorldWithLogger = withLogger(HelloWorld);
export default HelloWorldWithLogger;
- Usando
useCallbackpara Funções de Retorno
import React, { useState, useCallback } from 'react';
function Child({ increment }) {
return <button onClick={increment}>Incrementar</button>;
}
function Parent() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount((c) => c + 1);
}, []);
return (
<div>
<Child increment={increment} />
<p>Contagem: {count}</p>
</div>
);
}
export default Parent;
Exemplos 31 a 40:
- Implementando Rotas com
react-router-dom
import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function Home() {
return <h1>Home</h1>;
}
function About() {
return <h1>Sobre</h1>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">Sobre</Link>
</nav>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
export default App;
- Autenticação com Rotas Protegidas
import React from 'react';
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
const isAuthenticated = false;
function PrivateRoute({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={(props) =>
isAuthenticated ? <Component {...props} /> : <Redirect to="/" />
}
/>
);
}
function Dashboard() {
return <h1>Dashboard</h1>;
}
function App() {
return (
<Router>
<PrivateRoute path="/dashboard" component={Dashboard} />
</Router>
);
}
export default App;
- Carregamento de Dados com
useEffect
import React, { useEffect, useState } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => setData(json));
}, []);
return (
<div>
{data ? <p>{data.title}</p> : <p>Carregando...</p>}
</div>
);
}
export default DataFetcher;
- Custom Hooks
import React, { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
function App() {
const width = useWindowWidth();
return <
p>Largura da Janela: {width}px</p>;
}
export default App;
- Portal API do React
import React from 'react';
import ReactDOM from 'react-dom';
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.getElementById('modal-root')
);
}
function App() {
return (
<div>
<h1>Aplicação</h1>
<Modal>
<h2>Esse é um modal</h2>
</Modal>
</div>
);
}
export default App;
- Componente de Contexto com
useContext
import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<div>
<p>Tema Atual: {theme}</p>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Trocar Tema
</button>
</div>
);
}
export default App;
- Integrando com APIs RESTful
import React, { useEffect, useState } from 'react';
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => setUsers(json));
}, []);
return (
<div>
<h1>Usuários</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default Users;
- Manipulação de Erros com
Error Boundaries
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Algo deu errado.</h1>;
}
return this.props.children;
}
}
function BuggyComponent() {
throw new Error('Erro de Exemplo');
}
function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}
export default App;
- Animações com
react-spring
import React from 'react';
import { useSpring, animated } from 'react-spring';
function App() {
const props = useSpring({ opacity: 1, from: { opacity: 0 } });
return <animated.div style={props}>Eu apareço com animação!</animated.div>;
}
export default App;
- Usando Context API com Múltiplos Contextos
import React, { useContext, useState } from 'react';
const UserContext = React.createContext();
const ThemeContext = React.createContext();
function App() {
const [user, setUser] = useState('John Doe');
const [theme, setTheme] = useState('light');
return (
<UserContext.Provider value={user}>
<ThemeContext.Provider value={theme}>
<Content />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
function Content() {
const user = useContext(UserContext);
const theme = useContext(ThemeContext);
return (
<div>
<p>Usuário: {user}</p>
<p>Tema Atual: {theme}</p>
</div>
);
}
export default App;
Estes são os exemplos 31 a 40.
Exemplos 31 a 50:
- Implementando Rotas com
react-router-dom
import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function Home() {
return <h1>Home</h1>;
}
function About() {
return <h1>Sobre</h1>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">Sobre</Link>
</nav>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Router>
);
}
export default App;
- Autenticação com Rotas Protegidas
import React from 'react';
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
const isAuthenticated = false;
function PrivateRoute({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={(props) =>
isAuthenticated ? <Component {...props} /> : <Redirect to="/" />
}
/>
);
}
function Dashboard() {
return <h1>Dashboard</h1>;
}
function App() {
return (
<Router>
<PrivateRoute path="/dashboard" component={Dashboard} />
</Router>
);
}
export default App;
- Carregamento de Dados com
useEffect
import React, { useEffect, useState } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => setData(json));
}, []);
return (
<div>
{data ? <p>{data.title}</p> : <p>Carregando...</p>}
</div>
);
}
export default DataFetcher;
- Custom Hooks
import React, { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
function App() {
const width = useWindowWidth();
return <p>Largura da Janela: {width}px</p>;
}
export default App;
- Portal API do React
import React from 'react';
import ReactDOM from 'react-dom';
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.getElementById('modal-root')
);
}
function App() {
return (
<div>
<h1>Aplicação</h1>
<Modal>
<h2>Esse é um modal</h2>
</Modal>
</div>
);
}
export default App;
- Componente de Contexto com
useContext
import React, { useContext, useState } from 'react';
const ThemeContext = React.createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<div>
<p>Tema Atual: {theme}</p>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Trocar Tema
</button>
</div>
);
}
export default App;
- Integrando com APIs RESTful
import React, { useEffect, useState } from 'react';
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(json => setUsers(json));
}, []);
return (
<div>
<h1>Usuários</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default Users;
- Manipulação de Erros com
Error Boundaries
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Algo deu errado.</h1>;
}
return this.props.children;
}
}
function BuggyComponent() {
throw new Error('Erro de Exemplo');
}
function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}
export default App;
- Animações com
react-spring
import React from 'react';
import { useSpring, animated } from 'react-spring';
function App() {
const props = useSpring({ opacity: 1, from: { opacity: 0 } });
return <animated.div style={props}>Eu apareço com animação!</animated.div>;
}
export default App;
- Usando Context API com Múltiplos Contextos
import React, { useContext, useState } from 'react';
const UserContext = React.createContext();
const ThemeContext = React.createContext();
function App() {
const [user, setUser] = useState('John Doe');
const [theme, setTheme] = useState('light');
return (
<UserContext.Provider value={user}>
<ThemeContext.Provider value={theme}>
<Content />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
function Content() {
const user = useContext(UserContext);
const theme = useContext(ThemeContext);
return (
<div>
<p>Usuário: {user}</p>
<p>Tema Atual: {theme}</p>
</div>
);
}
export default App;
- Utilizando
useLayoutEffectpara Medições
import React, { useLayoutEffect, useRef, useState } from 'react';
function App() {
const [height, setHeight] = useState(0);
const ref = useRef(null);
useLayoutEffect(() => {
setHeight(ref.current.getBoundingClientRect().height);
}, []);
return (
<div>
<div ref={ref}>Eu sou um elemento!</div>
<p>Altura: {height}px</p>
</div>
);
}
export default App;
- Uso de
forwardRefpara Referências de Componente
import React, { forwardRef, useRef } from 'react';
const FancyButton = forwardRef((props, ref) => (
<button ref={ref} className="fancy-button">
{props.children}
</button>
));
function App() {
const buttonRef = useRef(null);
function handleClick() {
buttonRef.current.focus();
}
return (
<div>
<FancyButton ref={buttonRef}>Clique em Mim!</FancyButton>
<button onClick={handleClick}>Focar no Botão</button>
</div>
);
}
export default App;
- Implementando
React.memopara Componentes Otimizados
import React from 'react';
const ExpensiveComponent = React.memo(function ExpensiveComponent({ value }) {
console.log('Renderizando ExpensiveComponent');
return <div>{value}</div>;
});
function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<ExpensiveComponent value={count} />
<button onClick={() => setCount(count + 1)}>Incrementar</button>
</div>
);
}
export default App;
- Usando
useImperativeHandlepara Personalizar oref
import React, { useImperativeHandle, useRef, forwardRef } from 'react';
const CustomInput = forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
}));
return <input ref={inputRef} {...props} />;
});
function App() {
const inputRef = useRef(null);
return (
<div>
<CustomInput ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>Focar no Input</button>
</div>
);
}
export default App;
- Gerenciamento de Estado Global com
Redux
import React from 'react';
import { createStore } from 'redux';
import { Provider, useDispatch, useSelector } from 'react-redux';
const increment = () => ({ type: 'INCREMENT' });
const counterReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
const store = createStore(counterReducer);
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<p>Contador: {count}</p>
<button onClick={() => dispatch(increment())}>Incrementar</button>
</div>
);
}
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
export default App;
- Criando um Componente de Formulário Controlado
import React, { useState } from 'react';
function Form() {
const [name, setName] = useState('');
function handleChange(event) {
setName(event.target.value);
}
function handleSubmit(event) {
event.preventDefault();
alert(`Nome enviado: ${name}`);
}
return (
<form onSubmit={handleSubmit}>
<label>
Nome:
<input type="text" value={name} onChange={handleChange} />
</label>
<button type="submit">Enviar</button>
</form>
);
}
export default Form;
- Componente de Lista Dinâmica com
useReducer
import React, { useReducer } from 'react';
const reducer = (state, action) => {
switch (action.type) {
case 'ADD':
return [...state, action.payload];
case 'REMOVE':
return state.filter(item => item !== action.payload);
default:
return state;
}
};
function List() {
const [items, dispatch] = useReducer(reducer, []);
const [input, setInput] = React.useState('');
const addItem = () => {
dispatch({ type: 'ADD', payload: input });
setInput('');
};
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={addItem}>Adicionar</button>
<ul>
{items.map((item, index) => (
<li key={index}>
{item}
<button onClick={() => dispatch({ type: 'REMOVE', payload: item })}>
Remover
</button>
</li>
))}
</ul>
</div>
);
}
export default List;
- Utilizando
useCallbackpara Memorizar Funções
import React, { useState, useCallback } from 'react';
function Child({ onClick }) {
console.log('Renderizando Child');
return <button onClick={onClick}>Clique Aqui</button>;
}
function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<Child onClick={handleClick} />
<p>Contador: {count}</p>
</div>
);
}
export default App;
- Criando um Componente de Busca com Debounce
import React, { useState, useEffect } from 'react';
import _ from 'lodash';
function Search() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const fetchResults = (searchQuery) => {
// Simulação de chamada a API
setResults([`Resultado para "${searchQuery}"`]);
};
const debouncedFetch = _.debounce(fetchResults, 300);
useEffect(() => {
if (query) {
debouncedFetch(query);
}
}, [query]);
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Buscar..." />
<ul>
{results.map((result, index) => (
<li key={index}>{result}</li>
))}
</ul>
</div>
);
}
export default Search;
- Criando um Componente de Tabela com Dados Dinâmicos
import React, { useState } from 'react';
function Table() {
const [data, setData] = useState([
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
]);
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Idade</th>
</tr>
</thead>
<tbody>
{data.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.age}</td>
</tr>
))}
</tbody>
</table>
);
}
export default Table;
Estes exemplos cobrem uma ampla gama de funcionalidades e padrões no React, desde manipulação de estado até otimização de desempenho e integração com APIs.

Leave a comment