How to resolve "Typeerror: cannot read properties of null reading map" in React

How to resolve "Typeerror: cannot read properties of null reading map" in React

Introduction

In this article, we will be discussing a common error that may arise when building a React project. The error that may occur is the TypeError: Cannot read property 'map' of null which occurs when an array of elements set in state value evaluates to null when the map method is called on it.

Code snippets

For this article, I will be using the following code snippets to explain and resolve this error.


  const [allGratitude, setAllGratitude] = useState(null);
  const [gratitude, setGratitude] = useState({
    gratitudeForm: "",
    tag: "",
  });

  const handleGratitudeFormInputChange = (e) => {
    const { name, value } = e.target;
    setGratitude({
      ...gratitude,
      [name]: value,
    });
  };

  const handleGratitudeFormSubmit = (e) => {
    e.preventDefault();
    setGratitude({ gratitudeForm: "", tag: "" });
    if (gratitude.gratitudeForm && gratitude.tag) {
      setAllGratitude((prevArray) => [...prevArray, gratitude]);
      e.currentTarget.reset();
    } else {
      alert("fill all fields");
    }
  };

Explanation of Sample Code

The code snippet has two main state variables, allGratitude and gratitude. The allGratitude state variable is an array that holds all of the gratitude submitted by the user and set to null. The gratitude state variable is an object that holds the current form input of the user.

The handleGratitudeFormInputChange function is used to handle changes to the form input. It takes in the event object and destructures the name and value properties. It then updates the gratitude state variable using the spread operator to keep the previous state and only update the specific input that has changed.

The handleGratitudeFormSubmit function is used to handle the form submission. It takes in the event object and prevents the default form submission behavior. It then checks if the gratitudeForm and tag properties of the gratitude state variable have a truthy value. If they do, it concatenates the current gratitude to the allGratitude array and resets the form. If not, it alerts the user to fill in all fields.

Rendering the state in a component

import { useGlobalContext } from "../context";

const Dashboard = () => {
  const { allGratitude } = useGlobalContext();

  return (
    <div className="dashboard-container">
      {allGratitude.map((items, index) => {
        const { gratitudeForm, tag } = items;
        return (
          <article key={index}>
            <p>{gratitudeForm}</p>
            <button>{tag}</button>
          </article>
        );
      })}
    </div>
  );
};

export default Dashboard;

Explanation of rendered component

This code snippet utilizes a custom useGlobalContext hook to access the allGratitude state variable from the global context.

The component then uses a map method to loop through the allGratitude array and renders an article element for each item in the array. It destructures the gratitudeForm and tag properties from each item in the array and uses them to render the p and button elements respectively.

The key attribute is added to the article element to optimize the performance of the component when it updates and re-renders.

Reasons for the error

It's important to note that since the allGratitude state variable is set to null, this code will throw an error because the map method can only be called on arrays and not on null values.

The TypeError: Cannot read property 'map' of null error that occurs on this is because the allGratitude state variable is set to null and the map method is called on it. Hence, when your page renders, it automatically sees the allGratitude state array already in null, and throws the error immediately as the map method can only be called on arrays and not on null values.

Solution 1 - Set the initial state to empty array

To avoid this error, either the allGratitude state variable should be set to an empty array [] instead of null when the component first renders. This way, when the map method is called, it is called on an empty array and will not throw an error.

As seen below.

Solution 2 - conditional rendering

The second solution is to only render the component that utilizes the map method when the allGratitude state variable has a truthy value. This can be achieved by using a conditional rendering statement, such as an if statement, or the logical AND operator that checks if the allGratitude state variable is truthy before rendering the component that uses the map method.

So if your state variable is still set to null as seen below:

Your rendered component should look like this with the logical AND operator

So, the above code means that the map method will run only when there are elements present in the allGratitude state variable.

As seen below.

Conclusion

It's important to keep in mind that this error can occur when working with arrays and not specifically for the useState hook and that these solutions can be applied in similar situations.