1

I am currently building a web application with React with TypeScript. I am trying to fetch a custom-built API. However, it is returning too many of them. How do I access the whole API to do filtering of them after storing them in a state?

import React, { useEffect, useState } from "react";
import axios from "axios";

interface Invoice {
  id: number;
  customer_id: number;
  customer_name: string;
  date: string;
  total_invoice: number;
  total_margin: number;
  region: string;
  invoice_lines: [
    {
      product_id: number;
      product_name: string;
      unit_price: number;
      quantity: number;
      total_line: number;
      total_margin: number;
    }
  ];
}

function App() {
  const [data, setData] = useState<Invoice[]>([]);

  useEffect(() => {
    axios.get<Invoice[]>("http://localhost:3001/api/invoices").then(res => setData(res.data));
    console.log(data);
  }, []);

  return (
    <React.Fragment>
      <header>
        <h1>Hello</h1>
      </header>
      <main>
        {data.map(d => (
          <p key={d.id}>{d.customer_name}</p>
        ))}
      </main>
    </React.Fragment>
  );
}

export default App;
3
  • By too many objects, do you mean there are multiple responses? Commented Jun 29, 2021 at 18:02
  • I have added the response image Commented Jun 29, 2021 at 18:10
  • Refer to my answer below for the reason and solution. Commented Jun 29, 2021 at 18:20

2 Answers 2

1

Your useEffect hook is missing the dependency array, so it triggers upon every render. Add a dependency array. If you want the API to fetch once when the component mounts then use an empty dependency array, otherwise add a dependency on some value that the effect isn't data as this will cause render looping as well.

useEffect(() => {
  axios.get<Invoice[]>("http://localhost:3001/api/invoices")
    .then(res => setData(res.data));
}, []);

If you want to log state updates then separate this into it's own effect with specific dependency.

useEffect(() => {
  console.log(data);
}, [data]);
Sign up to request clarification or add additional context in comments.

Comments

0

This is happening because you are setting state inside a useEffect hook which is configured to react to every state change. So when your component is mounted, your useEffect is getting fired, which in turn is setting the state, causing your useEffect to fire again, and so on in an infinite loop. If you want your useEffect to execute only once, pass an empty array as a second parameter to your useEffect hook, like so:

useEffect(()->{
//your function body here
},[])

This will cause your useEffect to be executed only when your component is mounted, and never again. Refer to https://reactjs.org/docs/hooks-effect.html for more information on how the useEffect hook works.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.