You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js中控制台输出Undefined问题求助

问题:Google Place API请求返回JSON但控制台输出'Undefined'

点击按钮时,会将包含place_id的Google Place API请求结果传递给InfoPopup组件,API已成功返回JSON文件,但控制台却输出Undefined,怀疑首次渲染时ID未传递,但不知道如何解决。

父组件相关代码

const OnButtonClick = (restaurant) => {
    setRestaurant(restaurant)
    setOpenPopup(true)
}
<button className="cardButton" onClick={() => OnButtonClick(restaurantData)}>
    View Information
</button>
<InfoPopup open={openPopup} restaurant={restaurant} onClose={() => setOpenPopup(false)} />

InfoPopup组件代码

function InfoPopup({ open, onClose, restaurant }) { 
    const [restaurant1, setRestaurant1] = useState([])

    let id = restaurant.place_id
    let URL = `/maps/api/place/details/json?place_id=${id}&key=${process.env.REACT_APP_API_KEY}`
    const fetchRestaurants1 = async () => {
        const res1 = await axios.get(URL)
        setRestaurant1(res1.data.results);
      }

    useEffect(() => {
          fetchRestaurants1()
          console.log(restaurant1) // 这里输出'Undefined'
      }, [id]);
        

    const navigate = useNavigate()
    if (!open) {return null}
   

    return ReactDOM.createPortal(
    <>
        <div>
            {restaurant1?.map(restaurant => (
                <div key={restaurant.place_id}> {restaurant.formatted_phone_number} </div>
            ))}
        </div>
        <div className="popup">
            <div className="popup-inner">
                <button className="close-btn" onClick={onClose}> Close </button>
                <h1 className="title"> {restaurant.name} </h1>
            <ul>
                {/* <li className="service">
                    Status: {}
                </li> */}
                <li className="location">
                    Address: {restaurant.vicinity}
                    Phone Number: 
                </li>
                <li className="cost">
                    Cost: {restaurant.price_level}
                </li>
                {/* <li className="food">
                    Food Type:
                </li> */}
            </ul>
            <div className="links">
                <Link className="writeButton" to="/write" state={{data: restaurant}}>
                    Write a review
                </Link>
                {/* <button className="writeButton" onClick={() => navigate("/write", {data:restaurant})}>
                    Write a review
                </button> */}
                <Link className="readButton" to="/read" state={{data: restaurant}}>
                    Read the reviews
                </Link>
                {/* <button className="readButton" onClick={() => navigate("/read")}>
                    Read the reviews
                </button> */}
            </div>
            </div>
        </div>
    </>,
    document.getElementById('portal')
  )
}
解决方案

问题根源

  1. React状态更新是异步的:setRestaurant1调用后不会立即更新restaurant1状态,你在fetchRestaurants1后直接console.log(restaurant1),此时状态还没更新,所以输出undefined。
  2. 首次渲染时restaurant可能为空:父组件初始化时restaurant可能是未定义状态,直接取restaurant.place_id会导致报错,后续API请求失败,restaurant1保持初始空数组。
  3. API返回结构可能不匹配:Place Details API默认返回单个地点对象,而非数组,你用res1.data.results接收会拿到undefined。

修复步骤

  1. 正确处理异步状态的日志输出
    要么在API请求内部直接打印返回结果,要么监听restaurant1的变化再打印:

    const fetchRestaurants1 = async () => {
        const res1 = await axios.get(URL)
        console.log(res1.data); // 直接打印API返回的原始数据
        setRestaurant1(res1.data);
    }
    
    // 或者单独加监听状态变化的useEffect
    useEffect(() => {
        console.log(restaurant1);
    }, [restaurant1]);
    
  2. 添加空值判断,避免首次渲染报错
    在执行API请求前先确认restaurant和place_id存在,同时把请求逻辑放到useEffect内部,依赖改为restaurant:

    function InfoPopup({ open, onClose, restaurant }) { 
        const [restaurant1, setRestaurant1] = useState(null);
    
        useEffect(() => {
            // 先判断必要参数是否存在
            if (!restaurant?.place_id) return;
    
            const fetchRestaurantDetail = async () => {
                const URL = `/maps/api/place/details/json?place_id=${restaurant.place_id}&key=${process.env.REACT_APP_API_KEY}`;
                const res1 = await axios.get(URL);
                setRestaurant1(res1.data);
            };
    
            fetchRestaurantDetail();
        }, [restaurant]);
    
        // ...其他代码
    }
    
  3. 调整渲染逻辑匹配API返回结构
    Place Details API返回的是单个对象,不需要用map遍历,直接判断状态存在后渲染:

    // 替换原来的map部分
    <div>
        {restaurant1?.formatted_phone_number && (
            <div>{restaurant1.formatted_phone_number}</div>
        )}
    </div>
    

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 03:55:27