Home > Software design >  useEffect fails on page refresh
useEffect fails on page refresh

Time:03-01

I am an infant programmer and I am trying to fetch an api and style the results using React. My page works fine on the initial load and subsequent saves on VScode,but when I actually refresh the page from the browser I get the error thats posted on imageenter image description here:

Here is my code: App.js

```import React, { useEffect, useState } from 'react';
import './App.css';

import Students from './components/Students';
import styled from 'styled-components';

function App() {
  const [studentInfo, setStudentInfo] = useState({});
  const [searchResult, setSearchResult] = useState({});
  const [searchTerm, setSearchTerm] = useState('');
  useEffect(() => {
    getStudents();
  }, []);
  useEffect(() => {
    getStudents();
    console.log('useEffect');
  }, [searchTerm]);
  const getStudents = async () => {
    const url = 'https://api.hatchways.io/assessment/students';
    console.log(url);
    fetch(url)
      .then((res) => res.json())
      .then((data) => {
        console.log(data);
        searchTerm != ''
          ? setStudentInfo(filterStudents(data.students))
          : setStudentInfo(data.students);
      });
  };

    const filterStudents = (studentsArray) => {
    return studentsArray.filter((info) => {
      return (
        info.firstName.toLowerCase().includes(searchTerm) ||
        info.lastName.toLowerCase().includes(searchTerm)
      );
    });
  };
  console.log(searchTerm);

  return (
    <div className="App">
      <Students
        studentInfo={studentInfo}
        setSearchTerm={setSearchTerm}
        searchTerm={searchTerm}
      />
    </div>
  );
}

export default App;```

here is my component Students.js:

```import React, { useState } from 'react';
import styled from 'styled-components';
import GradeDetails from './GradeDetails';

const Students = ({ studentInfo, searchTerm, setSearchTerm }) => {
  console.log(typeof studentInfo);
  console.log(studentInfo[0]);
  const [isCollapsed, setIsCollapsed] = useState(false);

  const handleDetails = () => {
    setIsCollapsed(!isCollapsed);
  };
  const average = (arr) => {
    let sum = 0;
    arr.map((num) => {
      sum = sum   parseInt(num);
    });
    return sum / arr.length.toFixed(3);
  };
  console.log(isCollapsed);
  return (
    <Container>
      <Input
        type="text"
        value={searchTerm}
        placeholder="Search by name"
        onChange={(e) => setSearchTerm(e.target.value.toLowerCase())}
      />
      {studentInfo?.map((student) => (
        <Wrapper key={student.id}>
          <ImageContainer>
            <Image src={student.pic}></Image>
          </ImageContainer>
          <ContentContainer>
            <Name>
              {student.firstName} {student.lastName}{' '}
            </Name>
            <Email>Email: {student.email}</Email>
            <Company>Company: {student.company}</Company>
            <Skills>Skill: {student.skill}</Skills>

            <Average>Average:{average(student.grades)}%</Average>
          </ContentContainer>
          <ButtonContainer>
            <Button onClick={handleDetails}> </Button>
          </ButtonContainer>
          {isCollapsed && <GradeDetails studentInfo={studentInfo} />}
        </Wrapper>
      ))}
    </Container>
  );
};```

Every time I have the error, I comment out the codes in Students.js starting from studentInfo.map until the and save and then uncomment it and save and everything works fine again.

I am hoping someone can help me make this work every time so that I don't have to sit at the edge of my seat all the time. Thank you and I apologize for the long question.

CodePudding user response:

You are using an empty object as the initial state for studentInfo (the value passed to useState hook will be used as the default value - docs):

const [studentInfo, setStudentInfo] = useState({});

.map is only supported on Arrays. So this is failing when the component is rendering before the useEffect has completed and updated the value of studentInfo from an object, to an array. Try swapping your initial state to be an array instead:

const [studentInfo, setStudentInfo] = useState([]);
  • Related