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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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.
  10. 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:

  1. 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'));
  1. Criando um Componente Simples
   import React from 'react';

   function Welcome(props) {
     return <h1>Olá, {props.name}!</h1>;
   }

   export default Welcome;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. Componente de Classe Simples
   import React, { Component } from 'react';

   class Welcome extends Component {
     render() {
       return <h1>Olá, {this.props.name}!</h1>;
     }
   }

   export default Welcome;
  1. 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;
  1. 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;
  1. 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:

  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. Utilizando PropTypes para 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:

  1. Usando useReducer para 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. Uso de Memo para 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;
  1. 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;
  1. 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;
  1. 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;
  1. Usando useCallback para 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:

  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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:

  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. 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;
  1. Utilizando useLayoutEffect para 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;
  1. Uso de forwardRef para 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;
  1. Implementando React.memo para 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;
  1. Usando useImperativeHandle para Personalizar o ref
   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;
  1. 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;
  1. 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;
  1. 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;
  1. Utilizando useCallback para 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;
  1. 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;
  1. 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.

Edvaldo Guimrães Filho Avatar

Published by

Categories:

Leave a comment