【问题标题】:React.JS, how to edit the response of a first API call with data from a second API call?React.JS,如何使用来自第二个 API 调用的数据编辑第一个 API 调用的响应?
【发布时间】:2021-04-09 20:48:50
【问题描述】:

我需要在我的组件中显示一些数据,不幸的是,对我的 API 的第一次调用只返回了我想要显示的部分信息,以及一些 ID。我需要再次调用这些 ID 来检索其他有意义的数据。第一个调用包含在一个 useEffect() React.js 函数中:

useEffect(() => {
    const getData = async () => {
        try {
          const { data } = await fetchContext.authAxios.get(
            '/myapi/' + auth.authState.id
      );

    setData(data);
    } catch (err) {
        console.log(err);
    }
};
getData();
}, [fetchContext]);

并返回一个对象数组,每个对象代表给定Employee的约会,如下:

[
    {
        "appointmentID": 1,
        "employeeID": 1,
        "customerID": 1,
        "appointmentTime": "11:30",
        "confirmed": true
    },
... many more appointments
]

现在我还想检索有关客户的信息,例如姓名、电话号码等。我尝试设置另一种方法,例如 getData(),它会在我遍历各种约会时返回我需要的信息将它们显示为表格的行,但我学到了在渲染方法中调用的函数不应该有任何副作用的艰难方法。进行另一个 API 调用的最佳方法是什么,将每个“customerID”替换为存储客户 ID 和其他数据的对象?

[在我尝试过的方法之下,返回一个 [Object Promise]]

const AppointmentElements = () => {
    
//Loop through each Appointment to create a single row
    var output = Object.values(data).map((i) =>
                <Appointment 
                    key={i['appointmentID'].toString()} 
                    employee={i["employeeID"]} //returned a [Object premise]
                    customer={getEmployeeData((i['doctorID']))} //return a [Object Promise]
                    time={index['appointmentTime']} 
                    confirmed = {i['confirmed']}
                /> 
        
    );
        return output;
};  

【问题讨论】:

    标签: javascript reactjs axios


    【解决方案1】:

    正如您自己提到的,在渲染方法中调用的函数不应该有任何副作用,您不应该在渲染中调用 getEmployeeData 函数。

    您可以做的是,在您调用第一个 api 的同一个 useEffect 和同一个 getData 内,也调用第二个 api,嵌套在第一个 api 调用中,并将完整数据放入状态变量.然后在 render 方法中,循环遍历这个完整的数据,而不是第一个 api 的数据。

    如果您在调用 getData 中的第二个 api 时需要帮助,请告诉我,我会帮助您编写代码。

    更新(添加代码)

    您的useEffect 应该类似于:

    useEffect(() => {
        const getData = async () => {
            try {
                const { data } = await fetchContext.authAxios.get('/myapi/' + auth.authState.id);
                const updatedData = data.map(value => {
                        const { data } = await fetchContext.authAxios.get('/mySecondApi/?customerId=' + value.customerID);
                        // please make necessary changes to the api call
                        return {
                            ...value, // de-structuring
                            customerID: data
                            // as you asked customer data should replace the customerID field
                        }
                    }
                );
                setData(updatedData); // this data would contain the other details of customer in it's customerID field, along with all other fields returned by your first api call
            } catch (err) {
                console.log(err);
            }
        };
        getData();
    }, [fetchContext]);
    

    这是假设您有一个一次只接受一个客户 ID 的 api。


    如果你有更好的 api 接受客户 ID 列表,那么上面的代码可以修改为:

    useEffect(() => {
        const getData = async () => {
            try {
                const { data } = await fetchContext.authAxios.get('/myapi/' + auth.authState.id);
                const customerIdList = data.map(value => value.customerID);
                // this fetches list of all customer details in one go
                const customersDetails = (await fetchContext.authAxios.post('/mySecondApi/', {customerIdList})).data;
                // please make necessary changes to the api call
                const updatedData = data.map(value => {
                       // filtering the particular customer's detail and updating the data from first api call
                       const customerDetails = customersDetails.filter(c => c.customerID === value.customerID)[0];
                        
                        return {
                            ...value, // de-structuring
                            customerID: customerDetails
                            // as you asked customer data should replace the customerID field
                        }
                    }
                );
                setData(updatedData); // this data would contain the other details of customer in it's customerID field, along with all other fields returned by your first api call
            } catch (err) {
                console.log(err);
            }
        };
        getData();
    }, [fetchContext]);
    

    如果您的 api 支持,这将减少网络调用的数量和通常首选的方式。

    【讨论】:

    • 你好@Shubhaw,是的,我包括了“坏例子”,因为我希望对社区有所帮助。现在代码的问题实际上是进行第二次调用并将完整的数据放入状态变量中。
    • @WebStormer 我已经用代码更新了我的答案。第一个代码对第二个 api 进行多次调用,以一次获取一个客户详细信息。如果您的 api 支持一次获取多个客户数据,则可以使用第二种方法。
    • 第二个“await”出现以下编译错误:意外的保留字“await”。原因是因为在“value”变量之前缺少 async 关键字
    猜你喜欢
    • 2019-12-14
    • 2020-08-01
    • 1970-01-01
    • 2022-07-03
    • 1970-01-01
    • 2021-10-20
    • 2019-11-26
    • 2019-11-30
    • 2021-02-01
    相关资源
    最近更新 更多