**未捕获的类型错误:无法读取未定义的属性(读取‘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