Você está se deparando com o frustrante erro “TypeError: Cannot Read Property ‘Map’ of Undefined” em seu aplicativo React? Este erro pode ser complicado de depurar, mas não se preocupe – estamos aqui para ajudar.

Neste artigo, mostraremos a você as causas e soluções comuns para ajudá-lo a corrigir esse erro. Independentemente de você ser um desenvolvedor React experiente ou estar apenas começando, este guia ajudará você a colocar seu aplicativo de volta nos trilhos.

O que causa o erro “TypeError: Cannot Read Property ‘Map’ of Undefined”?

O erro “TypeError: Cannot Read Property ‘Map’ of Undefined” geralmente ocorre quando você tenta acessar uma propriedade ou método de um valor indefinido no código React.

Em termos simples, o erro ocorre quando você tenta mapear um valor indefinido, como uma array que não foi inicializada ou que ainda não recebeu dados.

No exemplo abaixo, você está obtendo itens de tarefas do JSON Placeholder, mas o método map é chamado antes que os dados de uma solicitação de API tenham chegado.

import { useState, useEffect } from 'react';

function App() {
  const [todos, setTodos] = useState();

  useEffect(() => {
    const getTodos = async () => {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/todos?_limit=5'
      );
      const data = await response.json();
      setTodos(data);
    };
    getTodos();
  }, []);

  console.log(todos);

  return (
    <div>
      {todos.map((todo) => (
        <div key={todo.id}>
          <h2>Item: {todo.title}</h2>
        </div>
      ))}
    </div>
  );
}

export default App;

O código acima lançará a mensagem “TypeError: Cannot read properties of undefined (reading ‘map’)”:

TypeError: Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of undefined (reading ‘map’)

Você precisa procurar uma maneira de permitir que o React saiba que o estado de todos é uma array, mesmo antes da array ser preenchida, ou precisa evitar que o método map seja executado até que a variável de estado de todos obtenha seus dados da solicitação de API.

3 maneiras de corrigir o erro “TypeError: Cannot Read Property ‘Map’ of Undefined”

Aqui estão três maneiras de corrigir o erro “TypeError: Cannot Read Property ‘Map’ of Undefined” no React:

  1. Inicialize sua variável de estado em um array vazio
  2. Use operadores de comparação
  3. Use o operador de encadeamento opcional (?.)

Vamos explorar cada uma dessas soluções e como elas podem ajudar você a resolver o erro em seu código React.

1. Inicialize sua variável de estado em um array vazio

Uma das soluções diretas para o erro “TypeError: Cannot Read Property ‘Map’ of Undefined” é garantir que a variável de array que você está tentando mapear esteja definida.

Você pode inicializar sua variável de estado com um array vazio por padrão, o que garantirá que a variável sempre exista e não gere um erro quando você tentar mapeá-la.

Por exemplo, a seguir estão dois componentes semelhantes, a variável de estado do primeiro não é inicializada com um array vazio, enquanto a do segundo é inicializada:

// Before initializing your state variable to an empty array
function MyComponent() {
  const [myList, setMyList] = useState();
  
  return (
    <ul>
      {myList.map(item => <li>{item}</li>)}
    </ul>
  );
}

// After initializing your state variable to an empty array
function MyComponent() {
  const [myList, setMyList] = useState([]);

  return (
    <ul>
      {myList.map(item => <li>{item}</li>)}
    </ul>
  );
}

No exemplo acima, a variável de estado myList é inicializada em uma array vazia por padrão usando useState([]). Isso garante que, mesmo que myList seja indefinido inicialmente, ele sempre será uma array e não lançará a mensagem “TypeError: Cannot Read Property ‘Map’ of Undefined”.

Para o exemplo de busca, você também pode inicializar a variável de estado todos como uma array vazia ([]):

import { useState, useEffect } from 'react';

function App() {
  // Initialize the state to an empty array of todos.
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    const getTodos = async () => {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/todos?_limit=5'
      );
      const data = await response.json();
      setTodos(data);
    };
    getTodos();
  }, []);

  console.log(todos);

  return (
    <div>
      {todos.map((todo) => (
        <div key={todo.id}>
          <h2>Item: {todo.title}</h2>
       </div>
      ))}
    </div>
  );
}

export default App;

2. Use operadores de comparação

Outra solução é usar operadores de comparação para verificar se a variável de array está definida antes de fazer o mapeamento sobre ela. Você pode usar o operador ternário ou lógico AND (&&) para fazer isso.

Aqui estão alguns exemplos de uso do operador ternário:

function MyComponent() {
  const [myList, setMyList] = useState();

  return (
    <ul>
      {myList ? myList.map(item => <li>{item}</li>) : null}
    </ul>
  );
}

Neste exemplo, você está verificando se a variável de array myList está definida antes de tentar mapeá-la. Se myList for indefinida, o operador ternário retornará null e nada será renderizado. Se myList estiver definida, a função map será chamada e os itens da lista serão renderizados.

Isso é semelhante ao uso do operador lógico AND:

function MyComponent() {
  const [myList, setMyList] = useState();

  return (
    <ul>
      {myList && myList.map(item => <li>{item}</li>)}
    </ul>
  );
}

Com o uso de operadores de comparação, como o operador ternário, você pode lidar com o carregamento, de modo que outra coisa seja exibida na tela enquanto você conduz os dados da API:

import { useState, useEffect } from 'react';

function App() {
  const [todos, setTodos] = useState();

  useEffect(() => {
    const getTodos = async () => {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/todos?_limit=5'
      );
      const data = await response.json();
      setTodos(data);
    };
    getTodos();
  }, []);

  console.log(todos);

  return (
   <div>
      {todos ? (
        todos.map((todo) => (
          <div key={todo.id}>
            <h2>Item: {todo.title}</h2>
          </div>
        ))
      ) : (
        <h1>Loading...</h1>
      )}
    </div>
  );
}

export default App;

3. Use o operador de encadeamento opcional (?.)

Você também pode usar o operador de encadeamento opcional (?.) introduzido no ES2020. Esse operador permite que você acesse com segurança propriedades ou métodos, como o método map de uma array, sem gerar um erro se o array estiver indefinido.

Aqui está um exemplo de um componente funcional que usa o operador de encadeamento para verificar a variável de estado myList:

function MyComponent() {
  const [myList, setMyList] = useState();

  return (
    <div>
      {myList?.map((item) => (
        <p>{item}</p>
      ))}
    </div>
  );
}

No exemplo acima, você está usando o operador de encadeamento opcional para acessar a variável de array myList com segurança. Se myList for indefinido, nada será renderizado. Se myList estiver definido, o método map será chamado e os itens da lista serão renderizados.

Resumo

O erro “TypeError: Cannot Read Property ‘Map’ of Undefined” pode ocorrer no React quando você usa o método map em um valor indefinido ou nulo.

Para corrigir esse erro, discutimos três soluções. No entanto, o uso de operadores de comparação é a solução mais versátil porque pode lidar com situações em que sua API pode enviar uma resposta vazia ou um valor nulo.

Além disso, quando não tiver certeza se os dados que você receberá serão um array, você pode adicionar alguns métodos para verificar e converter o tipo de dados antes de chamar o método map.

Confira a hospedagem de aplicativos da Kinsta e crie seu próximo projeto React hoje mesmo!

Agora é a sua vez: Você já encontrou esse problema? Como você o resolveu? Existem outras abordagens que você usou e que não foram abordadas neste artigo? Conte-nos na seção de comentários!