开发者问题收集

**未捕获的类型错误:无法读取未定义的属性(读取‘map’)**

2022-10-15
1703

我是 reactjs 的新手,被这个错误困住了,我尽我所能解决它,但我做不到 错误发生在第 38 行,地图所在的位置。我的数据集合在 app.jsx 中。当我运行它时, 它在屏幕上显示空白。谢谢,我真的很感谢你的帮助

这是我的 GroupedTeamMember.jsx

import { useState } from "react";

const GroupedTeamMembers = ({employees, selectedTeam, setTeam}) => {

    const [groupedEmployees, setGroupedData] = useState(groupTeamMembers);

    function groupTeamMembers() {
        var teams = [];

        var teamAMembers = employees.filter((employee) => employee.teamName === 'TeamA');
        var teamA = { team: 'TeamA', members: teamAMembers, collapsed: selectedTeam === 'TeamA'?false:true}
        teams.push(teamA);

        var teamBMembers = employees.filter((employee) => employee.teamName === 'TeamB');
        var teamB = { team: 'TeamB', members: teamBMembers, collapsed: selectedTeam === 'TeamB'?false:true}
        teams.push(teamB);

        var teamCMembers = employees.filter((employee) => employee.teamName === 'TeamC');
        var teamC = { team: 'TeamC', members: teamCMembers, collapsed: selectedTeam === 'TeamC'?false:true}
        teams.push(teamC);

        var teamDMembers = employees.filter((employee) => employee.teamName === 'TeamD');
        var teamD = { team: 'TeamD', members: teamDMembers, collapsed: selectedTeam === 'TeamD'?false:true}
        teams.push(teamD);
    }   

    function handleTeamClick(event) {
        var transformedGroupData = groupedEmployees.map((groupedData) => groupedData.team === event.currentTarget.id 
            ?{...groupedData, collapsed:!groupedData}
            :groupedData);

        setGroupedData(transformedGroupData);
        setTeam(event.currentTarget.id);
    }

    return (
        <main className="container">
           {
            groupedEmployees.map((item) => {
                return (
                    <div key ={item.team} className='card mt2' style={{cursor:"pointer"}} onClick={handleTeamClick}>
                        <h4 id={item.team} className="card-header text-secondary bg-white">
                            Team Name: {item.team}
                        </h4>
                        <div id={"collapse_" + item.team}
                            className={item.collapsed === true?"collap": ""}>
                            <hr />
                            {
                                item.members.map(member => {
                                    return (
                                        <div className="mt-2">
                                            <h5 className="card-title mt-2">
                                                <span className="text-dark">Full Name: {member.fullName}</span>
                                            </h5>
                                            <p>Designation: {member.designation}</p>
                                        </div>
                                    )
                                })
                            }
                        </div>
                    </div>
                )
            }) 
           }
        </main>
    );
};

export default GroupedTeamMembers;

import React from 'react';
import { useState, useEffect } from "react";
import Header from './Header';
import Footer from './Footer';
import GroupedTeamMembers from './GroupedTeamMembers';
import Nav from './nav';
import NotFound from './NotFound';
import './App.css';
import {BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Employees from './Employees';

function APP ()  {

  const [selectedTeam, setTeam] = useState(JSON.parse(localStorage.getItem('selectedTeam')) || 'TeamA');

  const [employees, setEmployees] = useState(JSON.parse(localStorage.getItem('employeeList')) || [{

          id: 1, 
          fullName: "Anas Isah", 
          designation: "JavaScript Developer",
          gender: "male",
          teamName:"TeamA"
      },
      {
          id: 2, 
          fullName: "Fatima Abubakr", 
          designation: "Node Developer",
          gender: "female", 
          teamName:"TeamA"
      },
      {
          id: 3, 
          fullName: "Hajru Buhari", 
          designation: "Java Developer",
          gender: "female",
          teamName:"TeamA"
      },
      {
          id: 4, 
          fullName: "Kabir Musa", 
          designation: "React Developer",
          gender: "male", 
          teamName:"TeamB"
      },
      {
          id: 5, 
          fullName: "David Henry", 
          designation: "DotNet Developer",
          gender: "male",
          teamName:"TeamB"
      },
      {
          id: 6, 
          fullName: "Sarah Blake", 
          designation: "JavaScript Developer",
          gender: "female", 
          teamName:"TeamB"
      },
      {
          id: 7, 
          fullName: "Tukur Isah", 
          designation: "Angular Developer",
          gender: "male",
          teamName:"TeamC"
      },
      {
          id: 8, 
          fullName: "Musa Sani", 
          designation: "API Developer",
          gender: "male", 
          teamName:"TeamC"
      },
      {
          id: 9, 
          fullName: "AIsah Isah", 
          designation: "C++ Developer",
          gender: "female",
          teamName:"TeamC"
      },
      {
          id: 10, 
          fullName: "Lawal Anas", 
          designation: "Python Developer",
          gender: "male", 
          teamName:"TeamD"
      },
      {
          id: 11, 
          fullName: "Jameel Wubni", 
          designation: "Vue Developer",
          gender: "male",
          teamName:"TeamD"
      },
      {
          id: 12, 
          fullName: "Abdul Nasir", 
          designation: "Graphic Designer",
          gender: "male", 
          teamName:"TeamD"
      }]);
      // It is going to change the state of employee when selected
      useEffect(() => {
        localStorage.setItem('employeeList',JSON.stringify(employees));
      },[employees]);
      // It is going to change the state of team when slected
      useEffect(() => {
        localStorage.setItem('selectedTeam',JSON.stringify(selectedTeam));
      },[selectedTeam]);

  function handleTeamSelectionChange(event){
      console.log(event.target.value);
      setTeam(event.target.value);
  }

  function handleEmployeeCardClick(event){
      const transformedEmployees = employees.map((employee) => employee.id === parseInt(event.currentTarget.id)
          ?(employee.teamName === selectedTeam)?{...employee, teamName: ''}:{...employee, teamName: selectedTeam}
          :employee);
      setEmployees(transformedEmployees);
  }; 
  return (
      <Router>
        <Nav />
        <Header 
              selectedTeam={selectedTeam}
              teamMemberCount={employees.filter((employee) => 
                employee.teamName === selectedTeam).length
              }
        />
            <Routes>
                <Route path='/'
                        element={<Employees employees={employees}
                        selectedTeam={selectedTeam}
                        handleEmployeeCardClick={handleEmployeeCardClick}
                        handleTeamSelectionChange={handleTeamSelectionChange} 
                        />}>
                </Route>
                <Route path='/GroupedTeamMembers' element={<GroupedTeamMembers 
                    employees={ employees} selectedTeam= {selectedTeam} 
                    setTeam= {setTeam} />} >
                </Route>
                <Route path='*' element={<NotFound />} >
                </Route>
            </Routes>
        <Footer />
      </Router>
  );
             
};

export default APP;
2个回答

GroupedTeamMembers 组件的第一行,您定义 groupedEmployees (您尝试在其上调用 .map 的对象),如下所示:

const [groupedEmployees, setGroupedData] = useState(groupTeamMembers);

groupTeamMembers 函数在第一次渲染时由 useState 调用以初始化 groupedEmployees 。但是, groupTeamMembers 函数从不返回值,因此 groupedEmployees 将被初始化为 undefined

我猜您想在 groupTeamMembers 函数末尾添加一个 return teams; 语句。

John Paul R
2022-10-16

React 中的钩子是异步的,因此无法保证在第一次渲染之前在开始时设置 groupedEmployees,因此它可能是未定义的。此外,函数 groupTeamMembers 不会返回任何内容,因此该值始终是未定义的。

最好的方法是将 groupTeamMembers 函数放在只运行一次并以此方式设置状态的使用效果中。

UseEeffect(() => {

function groupTeamMembers() {
        var teams = [];

        var teamAMembers = employees.filter((employee) => employee.teamName === 'TeamA');
        var teamA = { team: 'TeamA', members: teamAMembers, collapsed: selectedTeam === 'TeamA'?false:true}
        teams.push(teamA);

        var teamBMembers = employees.filter((employee) => employee.teamName === 'TeamB');
        var teamB = { team: 'TeamB', members: teamBMembers, collapsed: selectedTeam === 'TeamB'?false:true}
        teams.push(teamB);

        var teamCMembers = employees.filter((employee) => employee.teamName === 'TeamC');
        var teamC = { team: 'TeamC', members: teamCMembers, collapsed: selectedTeam === 'TeamC'?false:true}
        teams.push(teamC);

        var teamDMembers = employees.filter((employee) => employee.teamName === 'TeamD');
        var teamD = { team: 'TeamD', members: teamDMembers, collapsed: selectedTeam === 'TeamD'?false:true}
        teams.push(teamD);
        return teams;
    }   
 setGroupedData(groupTeamMembers());
}, [])

还有一件事是在渲染之前检查 groupedEmployees 的值,并且不要在开始时将状态设置为任何值

const [groupedEmployees, setGroupedData] = useState();

    return (
        <main className="container">
           {
            groupedEmployees && groupedEmployees.map((item) => {
                return (
                    <div key ={item.team} className='card mt2' style={{cursor:"pointer"}} onClick={handleTeamClick}>
                        <h4 id={item.team} className="card-header text-secondary bg-white">
                            Team Name: {item.team}
                        </h4>
                        <div id={"collapse_" + item.team}
                            className={item.collapsed === true?"collap": ""}>
                            <hr />
                            {
                                item.members.map(member => {
                                    return (
                                        <div className="mt-2">
                                            <h5 className="card-title mt-2">
                                                <span className="text-dark">Full Name: {member.fullName}</span>
                                            </h5>
                                            <p>Designation: {member.designation}</p>
                                        </div>
                                    )
                                })
                            }
                        </div>
                    </div>
                )
            }) 
           }
Mustafa
2022-10-16