¿Te encuentras con el frustrante error «TypeError: Cannot Read Property ‘Map’ of Undefined» («TypeError: No se puede leer la propiedad ‘Map’ de Undefined») en tu aplicación React? Este error puede ser difícil de depurar, pero no temas — te tenemos cubierto.

En este artículo, te guiaremos a través de las causas y soluciones más comunes para ayudarte a corregir este error. Tanto si eres un desarrollador React experimentado como si acabas de empezar, esta guía te ayudará a volver a poner en marcha tu aplicación.

¿Qué Causa el Error «TypeError: Cannot Read Property ‘Map’ of Undefined»?

El error «TypeError: Cannot Read Property ‘Map’ of Undefined» suele producirse cuando intentas acceder a una propiedad o método de valor indefinido en tu código React.

En términos sencillos, el error se produce cuando intentas mapear un valor indefinido, como un array que no se ha inicializado o que aún no ha recibido datos.

En el siguiente ejemplo, estás obteniendo elementos de tareas a partir de datos de Marcador de Posición JSON, pero el método map es llamado antes de que los datos de una petición API hayan llegado.

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;

El código anterior lanzará el error «»TypeError: Cannot read properties of undefined (reading ‘map’)»:

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

Tienes que buscar una forma de que React sepa que el estado «todos» es un array incluso antes de que el array se rellene, o tienes que evitar que el método map se ejecute hasta que la variable de estado todos obtenga sus datos de la solicitud de la API.

3 Formas de Solucionar el Error “TypeError: Cannot Read Property ‘Map’ of Undefined”

Aquí tienes tres formas de solucionar el error «TypeError: Cannot Read Property ‘Map’ of Undefined» en React:

  1. Inicializa tu variable de estado a un array vacío
  2. Utiliza operadores de comparación
  3. Utiliza el operador de encadenamiento opcional (?.)

Exploremos cada una de estas soluciones y cómo pueden ayudarte a resolver el error en tu código React.

1. Inicializa Tu Variable de Estado con un Array Vacío

Una de las soluciones directas al error «TypeError: Cannot Read Property ‘Map’ of Undefined» es asegurarte de que la variable del array a la que intentas asignar está definida.

Puedes inicializar tu variable de estado a un array vacío por defecto, lo que garantizará que la variable exista siempre y no genere un error cuando intentes mapearlo.

Por ejemplo, los siguientes son dos componentes similares, la variable de estado del primero no está inicializada a un array vacío, mientras que la del segundo sí lo está:

// 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>
  );
}

En el ejemplo anterior, la variable de estado myList se inicializa a un array vacío por defecto utilizando useState([]). Esto garantiza que, aunque myList no esté definida inicialmente, siempre será un array y no lanzará el error «TypeError: Cannot Read Property ‘Map’ of Undefined”.

Para el ejemplo de obtención, también puedes inicializar la variable de estado todos a un array vacío ([]):

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. Utilizar Operadores de Comparación

Otra solución es utilizar operadores de comparación para comprobar si la variable del array está definido antes de mapearlo. Puedes utilizar el operador ternario o lógico Y (&&) para conseguirlo.

Aquí tienes ejemplos de uso del operador ternario:

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

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

En este ejemplo, estás comprobando si la variable del array myList está definida antes de intentar mapearlo. Si myList no está definida, el operador ternario devuelve null, y no se renderiza nada. Si myList está definida, se llama a la función map y se muestran los elementos de la lista.

Esto es similar al uso del operador lógico Y:

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

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

Con el uso de operadores de comparación como el operador ternario, puedes manejar la carga, de modo que se muestre otra cosa en la pantalla mientras conduces los datos desde la 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. Utiliza el Operador de Encadenamiento Opcional (?.)

También puedes utilizar el operador opcional de encadenamiento (?.) introducido en ES2020. Este operador te permite acceder de forma segura a propiedades o métodos, como el método map de un array, sin lanzar un error si el array no está definido.

Aquí tienes un ejemplo de componente funcional que utiliza el operador de encadenamiento para comprobar la variable de estado myList:

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

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

En el ejemplo anterior, estás utilizando el operador de encadenamiento opcional para acceder de forma segura a la variable del array myList. Si myList está sin definir, no se renderizará nada. Si myList está definido, se llamará al método map y se renderizarán los elementos de la lista.

Resumen

El error «TypeError: Cannot Read Property ‘Map’ of Undefined» puede producirse en React al utilizar el método map sobre un valor indefinido o nulo.

Para solucionar este error, hemos analizado tres soluciones. Sin embargo, utilizar operadores de comparación es la solución más versátil porque puede manejar situaciones en las que tu API podría enviar una respuesta vacía o un valor nulo.

Además, cuando no estés seguro de si los datos que recibirás serán un array, puedes añadir algunos métodos para comprobar y convertir el tipo de datos antes de llamar al método map.

¡Echa un vistazo al Alojamiento de Aplicaciones de Kinsta y pon en marcha tu próximo proyecto React hoy mismo!

Ahora es tu turno: ¿Te has encontrado alguna vez con este problema? ¿Cómo lo resolviste? ¿Hay algún otro método que hayas utilizado y que no se haya mencionado en este artículo? ¡Háznoslo saber en los comentarios!