Home > OS >  Array not rendering in table within map function but console.logs
Array not rendering in table within map function but console.logs

Time:02-12

I am getting the personnel array data passed back from a child component. When I try console.log(personnel) before trying to render it, it prints it just fine, but when I try to render it inside the table by using the map function, it gives me nothing. I can't even console log inside the map function.

Here's my parent component where I want to render the personnel array inside a table.

function AllPersonnel(props) {

  let personnel = []
  let cols = [
    { path: "first_name", name: "First Name" },
    { path: "last_name", name: "Last Name" },
    { path: "section", name: "Section" },
    { path: "role", name: "Role" },
    { path: "employee_type", name: "Employee Type" },
  ];

  const handleCallback = (data) => {
    personnel.push(data)
  };
 
  return (
    <div>
      <h1>Personnel</h1>
      <div>
        {props.personnel.edges.map(({ node }) => {
          return (
            <Personnel
              key={node.__id}
              personnel={node}
              parentCallback={handleCallback}
            />
          );
        })}
      </div>

      <TableContainer component={Paper}>
        <Table>
          <TableHead>
            <TableRow>
              {cols.map((col) => {
                return <TableCell key={col.path}>{col.name}</TableCell>
              })}
            </TableRow>
          </TableHead>

          <TableBody>
            {console.log(personnel)} // this prints fine. will attach screenshot

            {personnel.map((row, i) => {
              {console.log("HERE")} // this does not print. I can't get into this map statement and I see no errors
              return (
                
                <TableRow key={row.id}>
                  
                  {console.log(row.first_name)}
                  <TableCell >
                    {row.first_name}
                  </TableCell>
                  <TableCell >{row.last_name}</TableCell>
                  <TableCell >{row.section}</TableCell>
                  <TableCell >{row.role}</TableCell>
                  <TableCell >{row.employee_type}</TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}

export default createFragmentContainer(AllPersonnel, {
  personnel: graphql`
    fragment AllPersonnel_personnel on PersonnelConnection {
      edges {
        node {
          ...Personnel_personnel
        }
      }
    }
  `,
});

my console log of the array shows all 252 elements perfectly

When I try using the useState hook instead of an array, it re-renders infinitely and gives me the error

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

Here is my child component. It's pretty simple, just sends back one row at a time to be added to the personnel object in the parent component.

function Personnel(props) {
  const data = [
    {
      id: props.personnel.id,
      first_name: props.personnel.first_name,
      last_name: props.personnel.last_name,
      section: props.personnel.section,
      role: props.personnel.role,
    },
  ];

  props.parentCallback(data); // sends back one row at a time, 252 times in this case

  return (
    <div></div>
  );
}

export default createFragmentContainer(Personnel, {
  personnel: graphql`
    fragment Personnel_personnel on Personnel {
      id
      first_name
      last_name
      section
      role
      employee_type
      PersonnelFromResource {
        position
        notes
      }
      PersonnelFromEngagement {
        cover_term
        sector
      }
    }
  `,
});

CodePudding user response:

personnel is a static array, the component won't re-render when it changes. To make the component re renders, you have to make it a state

so you import useState from react import React, {useState} from 'react; then change let personnel = [] to const [personnel , setPersonnel] = useState([]); and in the call back instead of personnel.push(data) you change it to setPersonnel((prevData)=>[...prevData , data])

  • Related