Im new in reactjs am stuck with this error I all try what I can do to resolved it but I could'nt The error is on line 38 wheere the map is. My data collection is inside th app.jsx. when I run it, it's showing me blank on the screen. Thanks I realy appriacite for your help
This is my 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;
CodePudding user response:
on the first line of the GroupedTeamMembers
component, you define groupedEmployees
(the thing you attempt to call .map
on) like so:
const [groupedEmployees, setGroupedData] = useState(groupTeamMembers);
This groupTeamMembers
function gets invoked by useState
on the first render to initialize groupedEmployees
. The groupTeamMembers
function, however, never returns a value, so groupedEmployees
will be initialized to undefined
.
My guess is that you want to add a return teams;
statement at the end of the groupTeamMembers
function.
CodePudding user response:
Hooks in react are asynchronous so there's no guarantee that groupedEmployees will be set at the beginning before the first render so it could be undefined. Also, the function groupTeamMembers isn't returning anything so the value would always be undefined.
The best approach would be to place groupTeamMembers function inside a use Effect which runs only once and sets the state that way.
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());
}, [])
One more thing is to check the value of groupedEmployees before rendering and don't set the state to anything at the beginning
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>
)
})
}