Hook useState - Estado Local

Módulo 3: Estado e Ciclo de Vida

Aula 1
1

Introdução ao Estado em React

15:00

Entenda o conceito de estado e sua importância em React

2

Exemplos Práticos com useState

Veja na prática como usar o useState em diferentes situações

Exemplos Práticos com useState

Exemplo 1: Contador Simples

import React, { useState } from 'react';

function Contador() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Você clicou {count} vezes</p>
      <button onClick={() => setCount(count + 1)}>
        Clique aqui
      </button>
    </div>
  );
}

Exemplo 2: Toggle de Visibilidade

function ToggleTexto() {
  const [mostrar, setMostrar] = useState(false);

  return (
    <div>
      <button onClick={() => setMostrar(!mostrar)}>
        {mostrar ? 'Esconder' : 'Mostrar'} Texto
      </button>
      {mostrar && <p>Este texto pode ser escondido!</p>}
    </div>
  );
}

Exemplo 3: Input Controlado

function FormularioNome() {
  const [nome, setNome] = useState('');

  return (
    <div>
      <input
        type="text"
        value={nome}
        onChange={(e) => setNome(e.target.value)}
        placeholder="Digite seu nome"
      />
      <p>Olá, {nome || 'visitante'}!</p>
    </div>
  );
}

Exemplo 4: Estado com Objetos

function PerfilUsuario() {
  const [usuario, setUsuario] = useState({
    nome: '',
    email: '',
    idade: 0
  });

  const atualizarCampo = (campo, valor) => {
    setUsuario(prevUsuario => ({
      ...prevUsuario,
      [campo]: valor
    }));
  };

  return (
    <div>
      <input
        placeholder="Nome"
        value={usuario.nome}
        onChange={(e) => atualizarCampo('nome', e.target.value)}
      />
      <input
        placeholder="Email"
        value={usuario.email}
        onChange={(e) => atualizarCampo('email', e.target.value)}
      />
      <input
        type="number"
        placeholder="Idade"
        value={usuario.idade}
        onChange={(e) => atualizarCampo('idade', parseInt(e.target.value))}
      />
    </div>
  );
}

Boas Práticas

1. Sempre use a função de atualização para estado baseado no anterior

// ❌ Evite
setCount(count + 1);

// ✅ Prefira
setCount(prevCount => prevCount + 1);

2. Não modifique o estado diretamente

// ❌ Evite
const usuario = { nome: 'João' };
usuario.nome = 'Maria'; // Mutação direta
setUsuario(usuario);

// ✅ Prefira
setUsuario({ ...usuario, nome: 'Maria' });

3. Estados múltiplos vs. estado único

// Múltiplos estados para valores independentes
const [nome, setNome] = useState('');
const [idade, setIdade] = useState(0);

// Estado único para valores relacionados
const [formData, setFormData] = useState({
  nome: '',
  idade: 0
});
3

Exercício: Contador Avançado

Pratique criando um contador com múltiplas funcionalidades

Activity

Exercício: Contador Avançado

Objetivo

Criar um componente de contador que permite:

  • Incrementar e decrementar
  • Resetar para zero
  • Definir um valor customizado
  • Não permitir valores negativos

Requisitos

  1. Use o hook useState para gerenciar o valor do contador
  2. Implemente 4 botões:
    • Incrementar (+1)
    • Decrementar (-1)
    • Resetar (volta para 0)
    • Definir valor (com input)
  3. O contador não deve aceitar valores negativos
  4. Mostre uma mensagem quando tentar decrementar abaixo de zero

Template Inicial

import React, { useState } from 'react';

function ContadorAvancado() {
  // Seu código aqui
  
  return (
    <div>
      {/* Implemente a interface aqui */}
    </div>
  );
}

export default ContadorAvancado;

Dicas

  • Use condicionais para verificar se o valor é maior que zero antes de decrementar
  • Para o input customizado, você precisará de um estado adicional
  • Lembre-se de converter o valor do input para número com parseInt()

Solução

Clique para ver a solução
import React, { useState } from 'react';

function ContadorAvancado() {
  const [contador, setContador] = useState(0);
  const [inputValor, setInputValor] = useState('');
  const [mensagem, setMensagem] = useState('');

  const incrementar = () => {
    setContador(contador + 1);
    setMensagem('');
  };

  const decrementar = () => {
    if (contador > 0) {
      setContador(contador - 1);
      setMensagem('');
    } else {
      setMensagem('O contador não pode ser negativo!');
    }
  };

  const resetar = () => {
    setContador(0);
    setMensagem('');
    setInputValor('');
  };

  const definirValor = () => {
    const novoValor = parseInt(inputValor);
    if (!isNaN(novoValor) && novoValor >= 0) {
      setContador(novoValor);
      setInputValor('');
      setMensagem('');
    } else {
      setMensagem('Por favor, insira um número válido maior ou igual a zero.');
    }
  };

  return (
    <div style={{ textAlign: 'center', padding: '20px' }}>
      <h1>Contador: {contador}</h1>
      
      <div style={{ margin: '20px' }}>
        <button onClick={incrementar}>+1</button>
        <button onClick={decrementar}>-1</button>
        <button onClick={resetar}>Resetar</button>
      </div>
      
      <div style={{ margin: '20px' }}>
        <input
          type="number"
          value={inputValor}
          onChange={(e) => setInputValor(e.target.value)}
          placeholder="Digite um valor"
        />
        <button onClick={definirValor}>Definir Valor</button>
      </div>
      
      {mensagem && <p style={{ color: 'red' }}>{mensagem}</p>}
    </div>
  );
}

export default ContadorAvancado;

Desafio Extra

Adicione as seguintes funcionalidades:

  • Botões para incrementar/decrementar de 5 em 5
  • Histórico dos últimos 5 valores
  • Limite máximo configurável
3 content items