devlog.blog

🧠 Como Criar Filtros Combinados em React com um Hook Personalizado (useSearchFilter)

✨ Introdução

Filtrar uma lista por um campo já é legal.
Mas e quando você quer filtrar por:

  • Nome e cidade?
  • Ou nome + email + status?

Neste post, vamos criar um sistema de filtros combinados em React — e o melhor: vamos transformar isso em um hook reutilizável, o useSearchFilter.

Com isso, você poderá aplicar filtros em qualquer lista, com qualquer critério, de forma simples, limpa e reutilizável.

Vamos lá? 🚀


🛠️ O que vamos fazer

  1. Usar a lista de usuários da API pública JSONPlaceholder
  2. Adicionar filtros por nome e cidade
  3. Criar um hook chamado useSearchFilter para aplicar múltiplos filtros de forma declarativa

🔧 Etapa 1: Hook useSearchFilter

🧠 O que esse hook faz:

ParteFunção
Object.entries(filters)Percorre cada filtro (ex: nome, cidade)
every()Garante que todos os filtros coincidam
includes()Faz a busca parcial (ex: “an” encontra “Ana”)

🧪 Etapa 2: Componente com Filtros Combinados

import { useEffect, useState } from 'react';
import { useSearchFilter } from './useSearchFilter';

export default function UsuariosComFiltro() {
  const [usuarios, setUsuarios] = useState([]);
  const [carregando, setCarregando] = useState(true);
  const [erro, setErro] = useState(null);

  const [filtros, setFiltros] = useState({
    name: '',
    city: ''
  });

  useEffect(() => {
    async function buscar() {
      try {
        const resp = await fetch('https://jsonplaceholder.typicode.com/users');
        const data = await resp.json();
        setUsuarios(data);
      } catch {
        setErro('Erro ao carregar dados.');
      } finally {
        setCarregando(false);
      }
    }

    buscar();
  }, []);

  const usuariosFiltrados = useSearchFilter(
    usuarios,
    {
      name: filtros.name,
      city: filtros.city
    }
  );

  if (carregando) return <p>Carregando...</p>;
  if (erro) return <p style={{ color: 'red' }}>{erro}</p>;

  return (
    <div style={{ maxWidth: '600px', margin: '0 auto' }}>
      <h2>Filtro de Usuários</h2>

      <input
        placeholder="Buscar por nome"
        value={filtros.name}
        onChange={(e) => setFiltros({ ...filtros, name: e.target.value })}
        style={{ padding: '8px', width: '100%', marginBottom: '10px' }}
      />

      <input
        placeholder="Buscar por cidade"
        value={filtros.city}
        onChange={(e) => setFiltros({ ...filtros, city: e.target.value })}
        style={{ padding: '8px', width: '100%', marginBottom: '20px' }}
      />

      {usuariosFiltrados.length === 0 ? (
        <p>Nenhum usuário encontrado.</p>
      ) : (
        <ul>
          {usuariosFiltrados.map(user => (
            <li key={user.id}>
              <strong>{user.name}</strong> — {user.address.city}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

✅ Resultado prático

Você poderá:

  • Digitar um nome E uma cidade ao mesmo tempo
  • Ver a lista atualizar em tempo real
  • Reutilizar o mesmo hook em qualquer lista do projeto

💡 Bônus: Quer deixar ainda mais avançado?

Aqui vão ideias para o próximo nível:

  • Aplicar debounce para evitar re-renderização em cada tecla
  • Usar o hook para filtros com checkbox ou selects
  • Salvar os filtros no localStorage ou na URL

Se quiser, posso montar esse próximo post também! 😉


📣 Conclusão

Você acabou de criar:

  • Um sistema de filtros múltiplos em React
  • Um hook personalizado que torna seu código reutilizável, limpo e escalável

Essa abordagem é ideal para:

  • Dashboards
  • Admins
  • E-commerce (filtro por categoria, preço, nome…)
  • Qualquer sistema que tenha busca combinada por campos

💡 Comece a usar o useSearchFilter sempre que tiver listas grandes para melhorar a experiência dos seus usuários.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *