Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for API call data before render react hooks

I make an API call.

It appears React goes ahead to build a table without the data, thus throwing error of

Uncaught TypeError: Cannot read property 'map' of undefined

Here's what I'm doing

useEffect() pretty straightforward

  const [data, setData] = useState();
  const [isBusy, setBusy] = useState()

  useEffect(() => {
    setBusy(true);
    async function fetchData() {
      const url = `${
        process.env.REACT_APP_API_BASE
        }/api/v1/endpoint/`;

      axios.get(url).then((response: any) => {
        setBusy(false);
        setData(response.data.results)
        console.log(response.data.results);
      });
    }

    fetchData();
  }, [])

Then I'm trying to render a table using the data from the API call above (as and when it becomes available)

            <div className="col-md-12 mt-5">
              {isBusy ? (
                <Loader />
              ) : (
                  <table className="table table-hover">
                    <thead>
                      <tr>
                        <th scope="col">Pharmacy User Full Name</th>
                        <th scope="col">Tests This Month</th>
                        <th scope="col">Tests This Week</th>
                        <th scope="col">Last Test Date</th>
                      </tr>
                    </thead>
                    <tbody>
                      {data.map((item: any, index: any) => {
                        return (<tr>
                          <th scope="row" key={index}>{item.name}</th>
                          <td>Mark</td>
                          <td>Otto</td>
                          <td>@mdo</td>
                        </tr>
                        )
                      })}

                    </tbody>
                  </table>
                )}
            </div>

The above appears intuitive enough for me. So not sure what I need to do. Thanks.

like image 213
KhoPhi Avatar asked Nov 20 '19 14:11

KhoPhi


People also ask

How do you wait for data in React?

To wait for a ReactJS component to finish updating, we use a loading state in our react application by use of the conditional rendering of the component. This can be achieved by the use of the useState and useEffect hooks in the functional components.

Does useEffect trigger before render?

If the useEffect function itself triggers another DOM mutation, this would happen after the first, but the process is usually pretty fast. Note: Although useEffect is deferred until after the browser has painted, it's guaranteed to fire before any new renders.

Why is Componentwillmount deprecated?

The reason for this decision is twofold: All three methods are frequently use incorrectly and there are better alternatives. When asynchronous rendering is implemented in React, misuse of these will be problematic, and the interrupting behavior of error handling could result in memory leaks.


1 Answers

You should set isBusy to true in the useState initial value

//                            initial value
const [isBusy, setBusy] = useState(true)

And also check data before data.map

// checking data
{data && data.map((item: any, index: any) => {
    return (<tr>
      <th scope="row" key={index}>{item.name}</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    )
})}
like image 150
Vencovsky Avatar answered Sep 24 '22 03:09

Vencovsky