Back

Corrigir 'TypeError: Cannot Read Property of Undefined' em JavaScript

Corrigir 'TypeError: Cannot Read Property of Undefined' em JavaScript

O erro “Cannot read property of undefined” interrompe mais aplicações JavaScript do que quase qualquer outro erro de runtime. Seja ao buscar dados de uma API, renderizar componentes React ou processar entrada do usuário, este TypeError do JavaScript aparece quando seu código tenta acessar uma propriedade em algo que ainda não existe.

Este artigo aborda por que este erro ocorre, como corrigi-lo com soluções modernas de JavaScript como optional chaining, e como preveni-lo em suas aplicações React e TypeScript.

Pontos-Chave

  • O TypeError ocorre quando o JavaScript tenta ler uma propriedade de undefined ou null
  • Optional chaining (?.) e nullish coalescing (??) fornecem soluções elegantes no JavaScript moderno
  • Erros no React frequentemente derivam de estado não inicializado ou dados assíncronos que não estão prontos
  • As verificações estritas de null do TypeScript detectam esses erros em tempo de compilação

Por Que Este Erro Acontece no JavaScript Moderno

O TypeError ocorre quando o JavaScript tenta ler uma propriedade de undefined. Você verá como “Cannot read property” ou “Cannot read properties” dependendo da versão do seu navegador—ambos se referem ao mesmo erro de runtime.

Causas Comuns no Mundo Real

Dados Assíncronos Ainda Não Prontos

// API data hasn't arrived
const [user, setUser] = useState()
return <div>{user.name}</div> // TypeError!

Estado React Não Inicializado

const [profile, setProfile] = useState() // undefined by default
useEffect(() => {
  console.log(profile.id) // Crashes immediately
}, [])

Acesso a Propriedades Profundas

// Server response might be incomplete
const city = response.data.user.address.city // Any level could be undefined

Esses cenários compartilham um problema de timing: seu código executa antes que os dados existam. No React, isso frequentemente acontece durante a primeira renderização ou quando o double-rendering do StrictMode em desenvolvimento expõe problemas de estado não inicializado.

Soluções Modernas: Optional Chaining e Nullish Coalescing

O JavaScript agora fornece soluções elegantes que substituem padrões de verificação verbosos. Esses recursos do ES2020+ são a abordagem padrão atualmente.

Optional Chaining (?.)

O optional chaining interrompe a avaliação quando encontra undefined ou null, retornando undefined em vez de lançar um erro:

// Modern approach (ES2020+)
const userName = user?.profile?.name
const firstItem = items?.[0]
const result = api?.getData?.()

// Old guard pattern (still works, but verbose)
const userName = user && user.profile && user.profile.name

Nullish Coalescing (??)

Combine optional chaining com nullish coalescing para fornecer valores de fallback:

// Only falls back for null/undefined (not empty strings or 0)
const displayName = user?.name ?? 'Anonymous'
const itemCount = data?.items?.length ?? 0

// Different from OR operator
const port = config?.port || 3000  // Falls back for 0, '', false
const port = config?.port ?? 3000  // Only for null/undefined

Padrões Específicos de Frameworks

React: Trate o Estado Undefined Adequadamente

Erros de undefined no React comumente ocorrem com estado não inicializado ou durante operações assíncronas:

function UserProfile() {
  // Initialize with null, not undefined
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetchUser().then(data => {
      setUser(data)
      setLoading(false)
    })
  }, [])

  // Conditional rendering prevents errors
  if (loading) return <div>Loading...</div>
  if (!user) return <div>No user found</div>
  
  // Safe to access user properties here
  return <div>{user.name}</div>
}

Importante: Não desabilite o StrictMode para “corrigir” problemas de double-rendering. Em vez disso, inicialize o estado adequadamente e use renderização condicional.

TypeScript: Prevenção em Tempo de Compilação

A segurança de null do TypeScript detecta esses erros antes do runtime através de verificações estritas de null:

// tsconfig.json
{
  "compilerOptions": {
    "strictNullChecks": true
  }
}

interface User {
  name: string
  email?: string // Optional property
}

function greetUser(user: User | undefined) {
  // TypeScript error: Object possibly 'undefined'
  console.log(user.name) // ❌
  
  // Correct approaches
  console.log(user?.name) // ✅
  if (user) console.log(user.name) // ✅
}

Aviso: Evite asserções non-null (user!.name) como uma “correção”—elas contornam a segurança do TypeScript e podem causar erros de runtime.

Melhores Práticas para Prevenção

Inicialize o Estado de Forma Significativa

// Bad: undefined state
const [data, setData] = useState()

// Good: explicit initial state
const [data, setData] = useState(null)
const [items, setItems] = useState([])
const [config, setConfig] = useState({ theme: 'light' })

Use Estados de Loading para Dados Assíncronos

function DataDisplay() {
  const [state, setState] = useState({
    data: null,
    loading: true,
    error: null
  })

  // Render based on state
  if (state.loading) return <Spinner />
  if (state.error) return <Error message={state.error} />
  if (!state.data) return <Empty />
  
  return <DataView data={state.data} />
}

Valide Respostas de API

async function fetchUserSafely(id) {
  try {
    const response = await api.get(`/users/${id}`)
    
    // Validate structure before using
    if (!response?.data?.user) {
      throw new Error('Invalid response structure')
    }
    
    return response.data.user
  } catch (error) {
    console.error('Fetch failed:', error)
    return null // Return predictable fallback
  }
}

Conclusão

O TypeError “Cannot read property of undefined” é fundamentalmente sobre timing e disponibilidade de dados. Os operadores optional chaining (?.) e nullish coalescing (??) do JavaScript moderno fornecem soluções limpas e legíveis que substituem padrões de verificação mais antigos. No React, a inicialização adequada do estado e a renderização condicional previnem a maioria dos problemas, enquanto as verificações estritas de null do TypeScript detectam erros em tempo de compilação.

A chave é reconhecer que valores undefined são naturais no mundo assíncrono do JavaScript—trate-os explicitamente em vez de esperar que não ocorram.

Perguntas Frequentes

Os componentes React renderizam imediatamente, e se seu estado inicial for undefined ou você estiver acessando propriedades aninhadas antes dos dados carregarem, o erro ocorre. Sempre inicialize o estado com valores padrão apropriados como null, arrays vazios ou objetos com a estrutura necessária.

Optional chaining tem impacto de performance negligenciável nos motores JavaScript modernos. Os benefícios de legibilidade e segurança superam em muito qualquer preocupação de micro-otimização. Use-o livremente, a menos que esteja em um loop comprovadamente crítico para performance.

Use o debugger do seu navegador para definir um breakpoint antes da linha, então inspecione cada nível no console. Alternativamente, registre temporariamente cada nível separadamente para identificar onde a cadeia quebra.

Try-catch deve tratar erros inesperados, não substituir verificações adequadas de null. Use optional chaining e renderização condicional para valores undefined esperados. Reserve try-catch para falhas de rede, erros de parsing e casos verdadeiramente excepcionais.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay