Geolocalização de IP em React: um componente de localização do visitante
Construa um hook useVisitorGeo reutilizável em torno do SDK JavaScript do Watch-IP, com o tratamento de carregamento, erro e cancelamento de que um componente React real precisa — incluindo porque é que o pedido pode disparar duas vezes em desenvolvimento.
Antes de começar
- Uma conta Watch-IP e uma chave de visitante publicável com a origem da sua aplicação (desenvolvimento e produção) na sua lista de origens permitidas.
- React 18 ou mais recente — o comportamento de dupla invocação do StrictMode descrito abaixo é específico do modo de desenvolvimento.
- @digitload/watch-ip-sdk instalado (npm install @digitload/watch-ip-sdk).
1. Construa um hook useVisitorGeo
Envolva a chamada getGeo() do SDK num hook que controla o estado de carregamento/resultado/erro e cancela o pedido se o componente for desmontado antes de ele ser resolvido.
TypeScript
import { useEffect, useState } from "react";
import { WatchIP, type GeoResponse } from "@digitload/watch-ip-sdk";
const client = new WatchIP("YOUR_PUBLISHABLE_KEY");
export function useVisitorGeo() {
const [geo, setGeo] = useState<GeoResponse | null>(null);
const [status, setStatus] = useState<"loading" | "ready" | "error">("loading");
useEffect(() => {
const controller = new AbortController();
client
.getGeo({ signal: controller.signal })
.then((result) => {
setGeo(result);
setStatus("ready");
})
.catch((err) => {
if (err.name !== "AbortError") setStatus("error");
});
return () => controller.abort();
}, []);
return { geo, status };
}2. Porque é que o pedido pode disparar duas vezes em desenvolvimento
O StrictMode do React monta, desmonta e volta a montar intencionalmente cada componente uma vez em desenvolvimento, para expor efeitos que não se limpam a si próprios. Isso significa que o efeito deste hook é executado duas vezes, e o AbortController acima é importante: o primeiro pedido é abortado pela função de limpeza antes de ser resolvido, pelo que apenas uma chamada real a getGeo() é efetivamente concluída. Ignorar a chamada de abort não comprometeria a correção — GET /v1/geo é uma leitura — mas deixaria um pedido em curso redundante e uma atualização de estado que a primeira instância descartada nunca utiliza.
3. Mostre os estados de carregamento, resultado e alternativa
Utilize o hook da mesma forma que utilizaria qualquer outro hook de dados, mantendo uma predefinição sensata visível até status deixar de ser 'loading'.
TypeScript (JSX)
function RegionBanner() {
const { geo, status } = useVisitorGeo();
if (status === "loading") return <p>A detetar a sua região…</p>;
if (status === "error" || !geo?.country) return <p>A mostrar a região predefinida</p>;
return <p>A mostrar conteúdo para {geo.city ?? geo.country}</p>;
}4. Preserve uma escolha explícita do visitante
Mesma regra do guia de JavaScript simples: verifique se existe uma preferência armazenada antes de aplicar o país sugerido, e só recorra ao resultado do hook quando ainda não existir preferência.
TypeScript
const preferred = localStorage.getItem("preferredCountry");
const country = preferred ?? geo?.country ?? "US";Erros e casos limite
Uma origem não permitida falha antes de o seu código ver uma resposta normal — adicione primeiro os URLs de desenvolvimento e produção da aplicação às origens permitidas da chave. Todos os campos de GeoResponse, exceto ip e isEUCountry, são anuláveis, pelo que status === 'ready' não é suficiente por si só; verifique também o campo específico que está prestes a apresentar, como a alternativa acima faz com geo?.country.
Próximo passo
Está a utilizar Next.js? O seu modelo de renderização no servidor altera onde este pedido pode ser executado com segurança — consulte o guia de Next.js para a divisão cliente/servidor e um padrão de servidor com chave secreta para IPs fornecidos.
Páginas relacionadas
- SDK de JavaScript@digitload/watch-ip-sdk no npm.
- Geolocalização do visitanteChame GET /v1/geo a partir do navegador com uma chave publicável.
- Referência de GET /v1/geoReferência completa de campos para o endpoint de geolocalização de visitante.
- Guia de Next.jsEscolha onde o seu pedido de localização em Next.js é executado.