1
resposta

"CEP inválido" não sumiu.

Mesmo depois que acrescentei o required no campo de CEP a mensagem de erro "CEP inválido" não some depois que eu coloco um CEP válido.

export default function CadastroEndereco() {
    const { setLoading, setClienteCriado } = useDataContext();
    const {
        formState: { errors },
        register,
        handleSubmit,
        setError,
        setValue,
        watch,
    } = useForm<IEndereco>();
    const cepDigitado = watch('cep');
    const navegarPara = useNavigate();

    function aoSubmeter(data: IEndereco) {
        const endereco = {...data}
        setClienteCriado(prev => ({ ...prev, endereco }));
        navegarPara('/sucesso');
    }

    async function buscaCep(cep: string) {
        if (!cep) {
            setError('cep', {
                type: 'manual',
                message: 'CEP inválido',
            });
            return;
        }

        setLoading(true);
        const endPoint = `https://viacep.com.br/ws/${cep}/json/`;

        try {
            const resposta = await fetch(endPoint);
            if (resposta.ok) {
                const dados = await resposta.json();
                setValue('rua', dados.logradouro);
                setValue('bairro', dados.bairro);
                setValue('localidade', `${dados.localidade}, ${dados.uf}`);
            } else {
                throw new Error(
                    `Erro na requisição do CEP: ${resposta.status} ${resposta.statusText}`,
                );
            }
        } catch (error) {
            console.error('Erro ao buscar CEP', error);
        } finally {
            setTimeout(() => setLoading(false), 1000);
        }
    }

    return (
        <>
            <Titulo>Agora, mais alguns dados sobre você:</Titulo>
            <Formulario onSubmit={handleSubmit(aoSubmeter)}>
                <Fieldset>
                    <Label htmlFor='campo-cep'>CEP</Label>
                    <Input
                        id='campo-cep'
                        placeholder='Insira seu CEP'
                        type='text'
                        {...register('cep', {
                            required: 'Este campo é obrigatório'
                        })}
                        $error={!!errors.cep}
                        onBlur={() => buscaCep(cepDigitado)}
                    />
                    {errors.cep && (
                        <ErrorMessage>{errors.cep.message}</ErrorMessage>
                    )}
                </Fieldset>
(...)

O que posso ter feito de errado?

1 resposta

Olá, estudante.

Tudo bem?

Isso pode estar acontecendo porque, mesmo após a busca do CEP, você não está limpando o erro manualmente. Você pode fazer isso utilizando o método clearErrors do react-hook-form.

Vou sugerir uma modificação no seu código para incluir essa correção. Veja como você pode fazer isso:

  1. Importe o método clearErrors do react-hook-form.
  2. Limpe o erro manualmente após a busca bem-sucedida do CEP.

Aqui está o código atualizado:

import React from 'react';
import { useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
import { useDataContext } from './DataContext';

export default function CadastroEndereco() {
    const { setLoading, setClienteCriado } = useDataContext();
    const {
        formState: { errors },
        register,
        handleSubmit,
        setError,
        setValue,
        watch,
        clearErrors, // Importa o clearErrors
    } = useForm<IEndereco>();
    const cepDigitado = watch('cep');
    const navegarPara = useNavigate();

    function aoSubmeter(data: IEndereco) {
        const endereco = {...data}
        setClienteCriado(prev => ({ ...prev, endereco }));
        navegarPara('/sucesso');
    }

    async function buscaCep(cep: string) {
        if (!cep) {
            setError('cep', {
                type: 'manual',
                message: 'CEP inválido',
            });
            return;
        }

        setLoading(true);
        const endPoint = `https://viacep.com.br/ws/${cep}/json/`;

        try {
            const resposta = await fetch(endPoint);
            if (resposta.ok) {
                const dados = await resposta.json();
                setValue('rua', dados.logradouro);
                setValue('bairro', dados.bairro);
                setValue('localidade', `${dados.localidade}, ${dados.uf}`);
                clearErrors('cep'); // Limpa o erro do CEP
            } else {
                throw new Error(
                    `Erro na requisição do CEP: ${resposta.status} ${resposta.statusText}`,
                );
            }
        } catch (error) {
            console.error('Erro ao buscar CEP', error);
        } finally {
            setTimeout(() => setLoading(false), 1000);
        }
    }

    return (
        <>
            <Titulo>Agora, mais alguns dados sobre você:</Titulo>
            <Formulario onSubmit={handleSubmit(aoSubmeter)}>
                <Fieldset>
                    <Label htmlFor='campo-cep'>CEP</Label>
                    <Input
                        id='campo-cep'
                        placeholder='Insira seu CEP'
                        type='text'
                        {...register('cep', {
                            required: 'Este campo é obrigatório'
                        })}
                        $error={!!errors.cep}
                        onBlur={() => buscaCep(cepDigitado)}
                    />
                    {errors.cep && (
                        <ErrorMessage>{errors.cep.message}</ErrorMessage>
                    )}
                </Fieldset>
                {/* ...outros campos... */}
            </Formulario>
        </>
    );
}

Com essa alteração, a mensagem de erro "CEP inválido" será removida quando um CEP válido for inserido e a busca for bem-sucedida.

É apensa uma sugestão de correção do problema, testa, veja se funciona e se faz sentido.

Espero ter ajudado. Qualquer dúvida manda aqui. Bons estudos.