Spec Frontend Com React • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 06.1 — Foco Automático em Input com useRef

Contexto: Foco Automático em Input com useRef no contexto de Acesso ao DOM e Valores Persistentes com useRef e useId.

Requisitos de Execução:

  1. Criar ref inputRef = useRef<HTMLInputElement>(null) e disparar inputRef.current?.focus() ao montar o componente.

Resultado Esperado

Campo de busca focado automaticamente no carregamento da página.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_06_1_SeuNome
  2. Envie na tarefa: Atividade Cap 06 - Acesso ao DOM e Valores Persistentes com useRef e useId
🔑 Gabarito de Código & Solução Comentada
// AutoFocusInput.tsx
import React, { useRef, useEffect } from 'react';

export const AutoFocusInput: React.FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} placeholder="Buscar..." />;
};

🔍 Nível 2: Prática

Problema 06.2 — Armazenamento de Valores Mutáveis sem Causar Re-render

Contexto: Armazenamento de Valores Mutáveis sem Causar Re-render no contexto de Acesso ao DOM e Valores Persistentes com useRef e useId.

Requisitos de Execução:

  1. Contabilizar total de re-renders de um componente usando renderCountRef = useRef(0).

Resultado Esperado

Contador de renders incrementado a cada renderização sem disparar loops infinitos.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_06_2_SeuNome
  2. Envie na tarefa: Atividade Cap 06 - Acesso ao DOM e Valores Persistentes com useRef e useId
🔑 Gabarito de Código & Solução Comentada
// RenderCounter.tsx
import React, { useRef, useEffect } from 'react';

export const RenderCounter: React.FC = () => {
  const renderCount = useRef(0);

  useEffect(() => {
    renderCount.current += 1;
    console.log('Total de renders:', renderCount.current);
  });

  return <div>Componente rastreado</div>;
};

⚡ Nível 3: Integração

Problema 06.3 — Geração de IDs Únicos Acessíveis com useId

Contexto: Geração de IDs Únicos Acessíveis com useId no contexto de Acesso ao DOM e Valores Persistentes com useRef e useId.

Requisitos de Execução:

  1. Utilizar const id = useId() para associar <label htmlFor={id}> com <input id={id}> de forma segura para SSR.

Resultado Esperado

IDs consistentes e acessíveis gerados sem colisões no cliente e servidor.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_06_3_SeuNome
  2. Envie na tarefa: Atividade Cap 06 - Acesso ao DOM e Valores Persistentes com useRef e useId
🔑 Gabarito de Código & Solução Comentada
// AccessibleInput.tsx
import React, { useId } from 'react';

export const AccessibleInput: React.FC<{ label: string }> = ({ label }) => {
  const id = useId();
  return (
    <div className="form-group">
      <label htmlFor={id}>{label}</label>
      <input id={id} type="text" />
    </div>
  );
};

🏆 Nível 4: Desafio Corporativo

Problema 06.4 — Encapsulamento de Elementos Nativos com forwardRef e useImperativeHandle

Contexto: Encapsulamento de Elementos Nativos com forwardRef e useImperativeHandle no contexto de Acesso ao DOM e Valores Persistentes com useRef e useId.

Requisitos de Execução:

  1. Criar componente customizado de input expondo apenas métodos específicos (focus, clear, shake) para o componente pai.

Resultado Esperado

Pai controla ações imperativas do input filho através de interface controlada.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_06_4_SeuNome
  2. Envie na tarefa: Atividade Cap 06 - Acesso ao DOM e Valores Persistentes com useRef e useId
🔑 Gabarito de Código & Solução Comentada
// CustomInputHandle.tsx
import React, { forwardRef, useImperativeHandle, useRef } from 'react';

export interface CustomInputRef { focus: () => void; clear: () => void; }

export const CustomInput = forwardRef<CustomInputRef>((props, ref) => {
  const internalRef = useRef<HTMLInputElement>(null);

  useImperativeHandle(ref, () => ({
    focus: () => internalRef.current?.focus(),
    clear: () => { if (internalRef.current) internalRef.current.value = ''; }
  }));

  return <input ref={internalRef} />;
});