【问题标题】:Why my useState from Context doesn't update为什么我的 Context 中的 useState 没有更新
【发布时间】:2021-07-14 22:06:05
【问题描述】:

您好,我尝试将数据从我的数据库保存到我的变量 selectedRestaurant。我在 useEffekt 挂钩中使用 setSelectedrestaurant,但它不会更新我的变量。我得到一个 null 值。

这是我的代码

import React, { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router';
import RestaurantFinder from '../api/RestaurantFinder';
import { RestaurantsContext } from "../context/RestaurantsContext";
import Reviews from '../components/Reviews';
import StarComponent from '../components/StarComponent';
import AddReview from '../components/AddReview';
import Test from '../components/Test';


const RestaurantDetailedPage = (props) =>{

    //const{ selectedRestaurant, setSelectedRestaurant}= createContext(RestaurantsContext);
const[ selectedRestaurant, setSelectedRestaurant]= useState(null);
    const {id} = useParams();

        useEffect(()=>{
          
            const fetchData = async(id)=>{
                
                const result = await RestaurantFinder.get("/"+id);
                console.log(result);
                setSelectedRestaurant(result.data.data); 
                console.log(selectedRestaurant);  
            }
            
        fetchData(id);
        },[]);//Wichtig, damit es nur 1x
/*
        useEffect(()=>{
          console.log("useEffect2");
          console.log(selectedRestaurant);
        },[selectedRestaurant]);
*/
        
    return(
        <div>{selectedRestaurant && (
            <>    
                
                <div>{<AddReview/>}</div>
                <div></div>
                </>
                )}
        </div>
        )

        

}

export default RestaurantDetailedPage;

我知道 useEffect 是异步的,所以我尝试使用 await setSelectedRestaurant(result.data.data) 但它没有用。我还定义了两个只能调用一次的 useEffects。一个用于更改,另一个用于更新,但两个 useEffects 都被调用了两次。我不知道为什么以及如何解决它。

希望你能帮助我

【问题讨论】:

    标签: reactjs axios react-hooks use-state


    【解决方案1】:

    尝试整理您的示例代码。有很多格式不佳的 cmets 和拼写错误导致解析变得困难。

    编辑:

    当您更新状态(即setSelectedRestraunt)时,这些更改会一起批处理,在下一个渲染循环之前不要更改状态变量。

    如果您想console.log 或以其他方式使用数据,请创建一个依赖于该值的 useEffect。

    import React, { useContext, useEffect, useState } from 'react';
    import { useParams } from 'react-router';
    import RestaurantFinder from '../api/RestaurantFinder';
    import { RestaurantsContext } from "../context/RestaurantsContext";
    import Reviews from '../components/Reviews';
    import StarComponent from '../components/StarComponent';
    import AddReview from '../components/AddReview';
    import Test from '../components/Test';
    
    
    const RestaurantDetailedPage = (props) =>{
    
        const{ selectedRestaurant, setSelectedRestaurant}= createContext(RestaurantsContext);
        const {id} = useParams();
    
            useEffect(()=>{
              
                const fetchData = async(id)=>{
                    
                    const result = await RestaurantFinder.get("/"+id);
                    console.log(result);
                    setSelectedRestaurant(result.data.data);  
                }
                
            fetchData(id);
            },[]);
    
            useEffect(()=>{
              console.log("Selected Restaurant:", selectedRestaurant);
            },[selectedRestaurant]);
            
        return(
            <div>{selectedRestaurant && (
                <>    
                    
                    <div>{<AddReview/>}</div>
                    <div></div>
                    </>
                    )}
            </div>
            )
    
            
    
    }
    
    export default RestaurantDetailedPage;
    
    

    原评论

    考虑到这一点,您的 &lt;Reviews&gt; 元素被注释掉了,这是故意的吗?

    {/* <Reviews reviewsObject={selectedRestaurant.reviews}/>*/}
    

    【讨论】:

    • 是的。因为我的 selectedUpdate 没有得到值或得到它太晚所以我在我的评论类中得到一个错误。它是空的,所以没有价值。我尝试让 setSelectedRestaurant 工作,然后看看其余的是否可以工作。
    • setState 操作是异步的,并且是一起批处理的。所以setSelectedRestaurant(result.data.data); console.log(selectedRestaurant); 不会注销result.data.data
    • 不只是它们是异步的,而是它们等待被批处理setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.所以让你的useEffect在console.log之前解决
    • 我怎么能允许它?我是反应新手,只是看了一些教程并阅读了一些网站。我有使用 then 命令吗?
    • 创建一个useEffect,它在依赖数组中有selectedRestraunt(在你当前的useEffect中,它是空的)。保留当前的,并创建第二个,它只注销新值。我将编辑我的答案以反映这一点
    猜你喜欢
    • 2021-02-27
    • 2021-02-13
    • 2021-07-13
    • 2018-03-21
    • 2011-10-10
    • 2018-03-13
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多