Home > Software design >  Component returning a blank screen in React: "Uncaught TypeError: Cannot read properties of und
Component returning a blank screen in React: "Uncaught TypeError: Cannot read properties of und

Time:11-03

The HeatMap component returns a blank screen, with the error occuring in the webpage console.

import React, { useState, useEffect } from "react";
import ClinicalRoom from '../images/ClinicalRoom.jpg'
import data3 from "../data.json"
import green from "../images/green.png"
import red from "../images/red.png"

export default function HeatMapTable({ list, colNames, room, height='auto'}) {
  const [count, setCount] = useState(0)
  const [backendData, setBackendData] = useState([{}])
   colNames = ["", "", "",""]
   
   useEffect(() => {
    fetch("/heatmapapi").then(
      response => response.json()
    ).then(
      data => {
        setBackendData(data)
      }
    )
  }, [count] ) 
  list = backendData[count].mapped
  room = backendData[count].room
  console.log(list)
  return (
    <div className="theme1">
      <h1>Heat Map</h1>
      <p1 >Room: {room}</p1>
      <button onClick={() => setCount(count - 1)}>Prev</button>
      <button onClick={() => setCount(count === 9 ? console.log("no more"): count 1)}>Next</button>
      <div className="layer"> 
        {list.length > 0 && (
          <table cellSpacing="0" style={{ height: height}}>
            <thead>
              <tr>
                {colNames.map((headerItem, index) => (
                  <th key={index}>
                    {headerItem.toUpperCase()}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {Object.values(list).map((obj, index) => (
              <tr key={index}>
                {Object.values(obj).map((value, index2) => (

                  <td  key={index2}>
                    {value === 0 ? <img className="map"src={green}/> : <img className="map" src={red}/>}
                    </td>
                ))}
              </tr>
              ))}
            </tbody>
          </table>
         )}
         <img className="room" src={ClinicalRoom}></img>
      </div>
    </div>
  )
}

The component is being rendered in App.js like this:

<Route path ="/heatmap" element={< HeatMap />} />

The component is grabbing the data from server.js using express like this:

const data2 = require("../client/src/data.json")

app.get("/heatmapapi", (req, res) => {
res.json(data2)})

The data inside the data.json file is inside of an array and looks like this:

          {"room": "101",
          "mapped": 
          [{"1":0, "2":1 ,"3":0, "4":1},
          {"1":0, "2":0, "3":0, "4":0},
          {"1":0, "2":0, "3":0, "4":0},
          {"1":0, "2":1, "3":0, "4":0},
          {"1":0, "2":0, "3":0, "4":0}],
            "staffnum": 1}

I have no idea why but the program runs perfectly with no errors if I do the following:

  1. run the program

  2. set list and room to:

    list = backendData room = backendData.room

  3. save and refresh

  4. set list and room back to:

    list = backendData[count].mapped room = backendData[count].room

  5. save and refresh

CodePudding user response:

Here's a representation of the initial (relevant) state of the component:
1- backenData = [{}]
2- count = 0
3- list = backendData[count].mapped

From 1- and 2- we can deduct that the derived state list is undefined.

When you're accessing list.length i.e undefined.length it throws an error. To manage the case where list would be undefined, you could use the optional chaining operator like this: list?.length

import React, { useState, useEffect } from "react";
...
export default function HeatMapTable({ list, colNames, room, height='auto'}) {
  ...
  return (
      ...
      <div className="layer"> 
        {list?.length > 0 && (
           ....
        )}
    }
  • Related