skip to Main Content

I have this list called reqs_needed. I want to update it based on the information an Axios request returns. This Axios.get request is inside a for loop because I want to get data back a certain number of times. However, my req_needed is not getting pushed to after I try pusing data to it.

My backend works fine as I can successfully send data back to the frontend and it will print correctly. It’s just not adding to the list at all.

Here is the code:

import "./SuggestedClasses.css";
import Axios from "axios";
import { useState, useEffect } from "react";
import TakenClass from "./types";
import {
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  TableContainer,
} from "@chakra-ui/react";

const SuggestedClasses = () => {
  const mapping: Record<number, string> = {
    0: "CI-H",
    1: "CI-M",
    2: "HASS-S",
    3: "HASS-H",
    4: "HASS-A",
  };

  localStorage.setItem("requirements_satisfied", "[2, 2, 1, 1, 1]");
  const requirements_satisfied = JSON.parse(
    localStorage.getItem("requirements_satisfied") as string
  );

  var reqs_filled = JSON.parse(
    localStorage.getItem("requirements_filled") as string
  );

  var reqs_needed: TakenClass[] = [];

  if (localStorage.getItem("requirements_filled") == null) {
    localStorage.setItem("requirements_filled", "[0, 0, 0, 0, 0]");
  }

  for (var i = 0; i < requirements_satisfied.length; i++) {
    if (reqs_filled[i] < requirements_satisfied[i]) {
      var j = 0;
      while (j < requirements_satisfied[i] - reqs_filled[i]) {
        var hass_attribute = null;
        var communication_requirement = null;
        if (mapping[i][0] === "C") {
          hass_attribute = null;
          communication_requirement = mapping[i];
        } else {
          hass_attribute = mapping[i];
          communication_requirement = null;
        }

        useEffect(() => {
          Axios.get("http://localhost:3000/getClass", {
            data: {
              hass_attribute: hass_attribute,
              communication_requirement: communication_requirement,
            },
          }).then((response) => {
            if (response.data) {
              reqs_needed.push(response.data);
            }
          });
        }, []);
        j++;
      }
    }
  }
  // console.log("reqs_needed", reqs_needed);
  console.log("reqs_needed.length", reqs_needed.length);
  for (var i = 0; i < reqs_needed.length; i++) {
    console.log("here");
    console.log("LOOPING", reqs_needed[i]);
  }

  return (
    <div className="suggestedClassesContainer">
      <h4 className="card-header">Suggested Classes</h4>
      <TableContainer>
        <Table variant="striped" colorScheme="teal">
          <Thead>
            <Tr>
              <Th>Num.</Th>
              <Th>Rating</Th>
            </Tr>
          </Thead>
          <Tbody>
            {reqs_needed.map((req: TakenClass) => {
              if (req != null) {
                return (
                  <Tr>
                    <Td>{req.subject_id}</Td>
                    <Td>{req.rating}</Td>
                  </Tr>
                );
              }
            })}
          </Tbody>
        </Table>
      </TableContainer>
    </div>
  );
};

export default SuggestedClasses;

The length of reqs_needed is always zero and causes nothing to show up in my frontend table.

2

Answers


  1. use state and add data inside that
    for example –

    const [reqNeeded, setReqNeeded] = useState([])
    

    insert the data inside the set useState –

    setReqNeeded[response.data]
    

    Hope it will help!!

    Login or Signup to reply.
  2. Obviously, you’re new to React so it’s best to learn basics of React first.

    But to answer your specific question, it’s not updating because a React component does not re-render until its states or props are updated.

    Your reqs_needed is just a variable inside your component and updating the variable does not re-render the component (meaning, re-draw it) because it’s not a state variable.

    So, you need to define it as a state variable like this:

    const [reqsNeeded, setReqsNeeded] = useState([]);
    

    And then set it:

    setReqsNeeded(newData);
    

    But loading all data directly inside the function body is not a good idea either because it’ll be re-run each time page re-renders, so you need to put it in useEffect block like this:

    useEffect(() => {
      // load data
    }, []);
    

    useEffect block with [] as second param runs only once at the start when your component mounts, so you can avoid re-loading data again and again.

    But, you want to pull data in an iteration and push all of them to reqs_needed, and setting the state is immutable which means you can’t edit the reqsNeeded state directly but setting a new state.

    So, you’d want to store all of your data in a local variable and then call setReqsNeeded at the end when the variable is ready.

    So, it’ll look like this:

    useEffect(() => {
      const newReqsNeeded = [];
    
      // load data
      for (...) {
        // ...
        newReqsNeeded.push(newValue);
      }
    
      // finally update the state
      setReqsNeeded(newReqsNeeded);
    }, []);
    

    You should notice I used camelCase rather than lower_case_with_hyphen because in JS, we usually use the former name pattern. Plus, if we name the final state variable reqs_needed, the setter method name will be weirdly setreqs_needed, which doesn’t look good.

    Anyway, as you can see, there are many problems in your code and it’s best to look at the React documentation first.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search