【问题标题】:I want to save variable as String through Axios response我想通过 Axios 响应将变量保存为字符串
【发布时间】:2022-06-27 07:36:51
【问题描述】:

我正在通过 Dot Net 6 和 React 开发一个简单的食品订购应用程序。

我有一张食物清单表,其中包含该特定食物的所有详细信息,包括提供该食物的餐厅。

在表格中,我想显示餐厅的名称,而不是来自食物数据的 ID。 list of foods

我的内在方法是使用这个函数

function getRestaurantById(id: number) {
    let res = '';
    axios.get('https://localhost:7005/api/Restaurant/' + id).then(response => {
        res = response.data.name;
    });
    return res;
}

当控制台登录 axios 的 .then() 方法时,我得到了我想要的餐厅名称。但是,res 变量被保存为未定义。我该如何解决这个问题?我希望这个函数返回一个字符串值。

注意:我不能(或者可能但不知道如何)使用 useState 函数,因为我将在表数据中调用此函数。

{foods.map(food => (
    <tr key={food.foodId}>
        <td>{food.foodId}</td>
        <td>{food.name}</td>
        <td>{food.ingredients}</td>
        <td>{food.price}</td>
        <td>{food.cuisineType}</td>
        <td>{getRestaurantById(food.restaurant)}</td>
        <td><Button className='btn' onClick={() => {setFood(food); handleFormOpen()}}>Edit</Button></td>
        <td><Button className='btn action' onClick={() => deleteFood(food.foodId.toString())}>Delete</Button></td>
    </tr>
))}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您的问题在于 axios.get() 的异步特性。 当请求运行时,它在函数的单独线程上运行,因此会更改操作顺序。我们将调用主线程线程 1.x 和 HTTP 请求线程 2.x。每个 x 都是我们在线程上执行的操作。

    function getRestaurantById(id: number) {
        // (1.1) We set res to an empty string.
        let res = '';
    
        // (1.2 -> 2.1) The request is called in thread 1 and started on thread 2.
        axios.get('https://localhost:7005/api/Restaurant/' + id).then(response => {
            // (2.2) We set the value of the reference to 'res' to response.data.name
            res = response.data.name;
        });
    
        // (1.3) return res
        return res;
    }
    

    现在按以下顺序操作:

    1.1 -> 1.2 -> 1.3
            |
             -> 2.1 -> 2.2
    

    由于在线程 2 上执行任务需要时间,因此 res 变量在 1.3 运行时不会更改。

    现在你可能会认为,既然引用被改变了,它会在 React 中更新,但它不会因为改变它自己的引用不会导致重新渲染。

    这是一个为满足您的需求而编写的组件(或者如果不是,它应该可以帮助您了解该去哪里):

    import React, {useState, useEffect} from 'react';
    import axios from 'axios';
    
    const foods = [
        {
            foodId: 1,
            name: 'Pizza',
            ingredients: 'Mozzarella, wheat, tomato, etc',
            price: 69,
            cuisineType: 'Italian',
            restaurant: 2
        }
    ]
    
    function Foods(food, handleDelete, handleEdit) {
        const [restaurant, setRestaurant] = useState(null);
    
        useEffect(() => {
            // With axios
            axios.get('https://localhost:7005/api/Restaurant/' + food.restaurant).then(response => setRestaurant(response.data));
    
            // With fetch
            fetch('https://localhost:7005/api/Restaurant/' + food.restaurant, {method: 'GET'})
                .then(r => r.json())
                .then(json => setRestaurant(json))
        }, [food.restaurant]);
    
        return (
            <tr>
                <td>{food.foodId}</td>
                <td>{food.name}</td>
                <td>{food.ingredients}</td>
                <td>{food.price}</td>
                <td>{food.cuisineType}</td>
                <td>{restaurant?.name}</td>
                <td><Button className='btn' onClick={() => handleEdit(food)}>Edit</Button></td>
                <td><Button className='btn action' onClick={() => handleDelete(food.foodId.toString())}>Delete</Button></td>
            </tr>
        )
    }
    
    export default function Foo() {
        return foods.map(food => (<Foods foods={food} handleEdit={(food) => console.log('Tried to edit: ', food)} handleDelete={(food) => console.log('Tried to delete: ', food)}/>))
    }
    

    编辑: 上面我提到了在单独的线程上运行的代码,我最近了解到这在技术上是不正确的。 JS 使用“事件循环”(除非您使用 WebWorker)来模拟多线程的功能。更多信息可以在这里找到:https://blog.logrocket.com/a-complete-guide-to-the-node-js-event-loop/

    【讨论】:

    • 这正是我所需要的。我解决了这个问题,谢谢!
    【解决方案2】:

    我建议您从后端本身获取带有食物列表的餐厅名称,因为现在您正在调用获取请求的每种食物。因此,如果有 1000 种食物,您将为每种食物调用 1000 次请求,这不是一个好主意。

    【讨论】:

    • 我将来也会对此进行研究。感谢您的意见!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 2019-08-19
    相关资源
    最近更新 更多