The React component fails to load due to the discrepancies in the data retrieved from various asynchronous requests

Creating a travel-related form using React with TypeScript. The initial component

TravelForm

utilizes multiple async-await requests within useEffect hook to update the state of the subsequent component

TravelGuideFields

However, the values of props are not being displayed in my TravelGuideFields component. Upon inspection with React dev tool, the state is correctly updated with new values, but it seems like the component is loading with old values. This could be due to the multiple async-await calls causing the component to render before obtaining the final result value. Is there an alternative way to ensure my components display the updated values?

Here is the first component where the multiple network calls are made within the effect hook:

import { FC, useEffect, useState } from "react";
import {
    getOrderedbooks,
    getOrderedSportsGears,
    getOrderedTravelMaps
} from "../../httpRequests/TravelRequests";

import TravelGuideFields from "./TravelGuideFields";

const TravelForm: FC = () => {
    // states
    const [inputs, setInputs] = useState<TravelInputInterface>({
        bookName: "",
        bookPrice: 0.0,
        runningShoeBrand: "",
        runningShoeCost: 0.0,
        mapType: "",
        mapCost: 0.0,
    });

    useEffect(() => {
        const resultInputs: TravelInputInterface = {
             bookName: "",
             bookPrice: 0.0,
             runningShoeBrand: "",
             runningShoeCost: 0.0,
             mapType: "",
             mapCost: 0.0,
        };
        const fetchBooks = async () => {
            const res = await getOrderedbooks();
        

            if (res !== undefined) {
                resultInputs.bookName = res.BOOK_NAME;
                resultInputs.bookPrice = res.BOOK_PRICE;
          
            }
        };
        fetchBooks();

        const fetchSportsGear = async () => {
            const res = await getOrderedSportsGears();
        

            if (res !== undefined) {
                resultInputs.runningShoeBrand = res.SHOE_BRAND;
                resultInputs.bookPrice = res.SHOE_PRICE;
          
            }
        };
        fetchSportsGear();

        const fetchTravelMaps = async () => {
            const res = await getOrderedTravelMaps();
            
            if (res !== undefined) {
                resultInputs.mapType = res.MAP_TYPE;
                resultInputs.mapCost = res.MAP_COST;
       
            }
        };

        fetchTravelMaps();
        console.log({ resultInputs });
        setInputs(resultInputs);
    }, []);

    
    return <TravelGuideFormFields inputs={inputs} />;
};
default BlockchainConstantsForm;

//TravelGuideFields component

const TravelGuideFields: FC<any> = ({inputs}) => {

return (
<div>
<div class="books"><input value={inputs.bookName} disabled/>
<input value={inputs.bookPrice} disabled/></div>
<div class="maps"><input value={inputs.mapType} disabled/></div>
<div class="sports"><input value={inputs.runningShoe} disabled/></div>
</div>
)
}

export default TravelGuideFields

//TravelRequests (HTTP request generator file)

//Books
export const getOrderedbooks = async (): Promise<bookInterface | undefined> => {
    const res = await get(
         `${mainURL}/books`
     );
    
    if (res.status === 200) {
        
        return res.data;
    }

    return undefined;
};

//SportsGear

export const getOrderedSportsGears = async (): Promise<sportsInterface | undefined> => {
        const res = await get(
             `${mainURL}/sports`
         );
        
        if (res.status === 200) {
            
            return res.data;
        }
    
        return undefined;
    };

//Travelmaps

    export const getOrderedTravelMaps = async (): Promise<mapInterface | undefined> => {
            const res = await get(
                 `${mainURL}/map`
             );
            
            if (res.status === 200) {
                
                return res.data;
            }
        
            return undefined;
        };

Answer №1

Here is where the issue lies.

The code lacks consistency in using async-await throughout.

    useEffect(() => {
        const resultInputs: TravelInputInterface = {
             bookName: "",
             bookPrice: 0.0,
             runningShoeBrand: "",
             runningShoeCost: 0.0,
             mapType: "",
             mapCost: 0.0,
        };
        const fetchBooks = async () => {
            const res = await getOrderedbooks();
        

            if (res !== undefined) {
                resultInputs.bookName = res.BOOK_NAME;
                resultInputs.bookPrice = res.BOOK_PRICE;
          
            }
        };
        fetchBooks();

        const fetchSportsGear = async () => {
            const res = await getOrderedSportsGears();
        

            if (res !== undefined) {
                resultInputs.runningShoeBrand = res.SHOE_BRAND;
                resultInputs.bookPrice = res.SHOE_PRICE;
          
            }
        };
        fetchSportsGear();

        const fetchTravelMaps = async () => {
            const res = await getOrderedTravelMaps();
            
            if (res !== undefined) {
                resultInputs.mapType = res.MAP_TYPE;
                resultInputs.mapCost = res.MAP_COST;
       
            }
        };

        fetchTravelMaps();
        console.log({ resultInputs });
        setInputs(resultInputs);
    }, []);

The above code snippet indicates the problem area.

To resolve this, you can modify the code as follows:

    useEffect(() => {
        const promises = [getOrderedbooks, getOrderedSportsGears, getOrderedTravelMaps];

        Promise.all(promises).then(promises => {
            const [booksResponse, sportsGearResponse, travelMapsResponse] = promises;

            const resultInputs: TravelInputInterface = {
                bookName: "",
                bookPrice: 0.0,
                runningShoeBrand: "",
                runningShoeCost: 0.0,
                mapType: "",
                mapCost: 0.0,
           };

            if (booksResponse !== undefined){
                resultInputs.bookName = booksResponse.BOOK_NAME;
                resultInputs.bookPrice = booksResponse.BOOK_PRICE;
            }

            if (sportsGearResponse !== undefined){
                resultInputs.runningShoeBrand = sportsGearResponse.SHOE_BRAND;
                resultInputs.bookPrice = sportsGearResponse.SHOE_PRICE;
            }

            if (travelMapsResponse !== undefined) {
                resultInputs.mapType = travelMapsResponse.MAP_TYPE;
                resultInputs.mapCost = travelMapsResponse.MAP_COST;
            }

            setInputs(resultInputs);
        })        
    }, []);

Using Promise.all guarantees that the logic runs after all API calls are completed. As useEffect cannot be an async function, using .then provides a cleaner alternative to utilizing async-await.

If desired, you can still employ async-await by encapsulating the entire useEffect within another async function and invoking it inside the useEffect.

Answer №2

Have you considered using promise.all() with await? Missing the await keyword can result in a promise being returned instead of the desired data. Give this code snippet a try and inform me of whether or not it resolves your issue:

const [booksResponse, sportsGearResponse , travelMapsResponse] = await 
Promise.all([
getOrderedbooks(),
getOrderedSportsGears(),
getOrderedTravelMaps(),
]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Understanding the operational aspects of Typescript's target and lib settings

When the tsconfig.json file is configured like this: "target": "es5", "lib": [ "es6", "dom", "es2017" ] It appears that es2017 features are not being converted to es5. For example, code like the following will fail in IE11: var foo = [1, 2, 3].includes( ...

Can you explain the purpose of useEffect in React?

As a beginner in learning React, I have been able to grasp the concept of the useState hook quite well. However, I am facing some difficulties understanding the useEffect hook. I have tried looking through the documentation, searching online, and even wat ...

Whenever I try to load the page and access the p-tableHeaderCheckbox in Angular (primeng), the checkbox appears to be disabled and I am unable to

I attempted to use the disabled attribute on p-tableheadercheckbox in order to activate the checkbox. <p-tableHeaderCheckbox [disabled]="false"></p-tableHeaderCheckbox> <ng-template pTemplate="header"> <tr> ...

Tips for utilizing a ternary operator to set a className in an element

I'm in the process of developing a website using React and Next.js. One of the components on my site is section.tsx, which displays a subsection of an article based on the provided props. I'm looking to add an 'align' property to this c ...

How can I effectively halt the influx of streaming updates from an RTKQ?

Attempting to invoke an unsubscribe function: unsubscribeFromThingIds(arg.tids); following the await cacheEntryRemoved; statement in this specific example. The definition of the function is as follows: export const unsubscribeFromThingIds = (tids: string ...

Is it possible to combine TypeScript modules into a single JavaScript file?

Hey there, I'm feeling completely lost with this. I've just started diving into Typescript with Grunt JS and I could really use some assistance. I already have a Grunt file set up that runs my TS files through an uglify process for preparing the ...

Tips for importing several makeStyles in tss-react

When upgrading from MUI4 to MUI5 using tss-react, we encountered a problem with multiple styles imports in some files. const { classes } = GridStyles(); const { classes } = IntakeTableStyles(); const { classes } = CommonThemeStyles(); This resulted in ...

Disabling breakpoints without bounds during TypeScript debugging in Visual Studio Code

While working on my Ubuntu machine using VS Code to debug a Nest.js TypeScript project, I am encountering issues with unbound breakpoints that are not being hit. Despite making various changes in the launch.json and tsconfig.json files, as well as trying o ...

What is the best way to reproduce the appearance of a div from a web page when printing using typescript in Angular 4?

Whenever I try to print a div from the webpage, the elements of the div end up on the side of the print tab instead. How can I fix this issue? Below is my current print function: print(): void { let printContents, popupWin; printContents = document.getEl ...

Tips for relocating the indicators of a react-material-ui-carousel

I am working with a carousel and dots indicators, but I want to move the indicators from the bottom to the circular position as shown in the image below. I attempted using a negative margin-top, but the indicators ended up being hidden. Is there another ...

Encountering issues with accessing properties of undefined while chaining methods

When comparing lists using an extension method that calls a comparer, I encountered an error. Here is the code snippet: type HasDiff<T> = (object: T, row: any) => boolean; export const isListEqualToRows = <T>(objects: T[], rows: any[], has ...

Injecting Variables Into User-Defined Button

Presenting a custom button with the following code snippet: export default function CustomButton(isValid: any, email: any) { return ( <Button type="submit" disabled={!isValid || !email} style={{ ...

Encountering an error in Angular 4: 'Cannot find property on specified component type'

I recently embarked on the journey of learning Angular 4 and TypeScript, but I've encountered my first obstacle. My current challenge involves creating a simple date and time component. Despite having a seemingly correct Javascript code, I believe I ...

Searching Local JSON Data in Ionic 4 with a Filter Input Bar

My current challenge involves filtering local JSON data in my Ionic project. Despite referencing other resources, I am unable to filter or display filtered items on the ngx-datatable. I suspect the issue may lie either in the filterItems function implement ...

Problem encountered in NextJS/ReactJS when attempting to dynamically load a new component by clicking a button within the current component

In my NextJS project, I am working with 3 components named "Sidebar", "Woven", and "ToolsPage". Below are the respective codes for each: ToolsPage Component: "use client" import Woven from './components/weaved'; import Sidebar from &ap ...

Interface-derived properties

One of the challenges I'm facing is dealing with a time interval encapsulation interface in TypeScript: export interface TimeBased { start_time: Date; end_time: Date; duration_in_hours: number; } To implement this interface, I've created ...

TypeScript's conditional property failing to recognize incorrect functional argument

The concept of a conditional type should encompass smart properties, and I sought assistance from @jcalz in the previous iteration of this query. Even though that issue was resolved, I am still unable to achieve the level of typing strictness I desire. The ...

specialized registration process with auth0 in Angular

I am attempting to enhance the user information in a single call. The process involves first signing up with a username and password on Auth0, followed by adding additional userinfo to the database during the callback phase. However, I am encountering diff ...

Use React hooks to submit a form after updating the state

Seeking guidance on utilizing the latest react hooks. How can I update the state and then proceed to submit a form? For instance, I have a search box that relies on the typical state managed by setSearch, where upon submission, it queries data from the se ...

Getting Session from Next-Auth in API Route: A Step-by-Step Guide

When printing my session from Next Auth in a component like this, I can easily see all of its data. const session = useSession(); // ... <p>{JSON.stringify(session)}</p> I am facing an issue where I need to access the content of the session i ...