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') ) }
解决方案
问题根源
- React状态更新是异步的:
setRestaurant1调用后不会立即更新restaurant1状态,你在fetchRestaurants1后直接console.log(restaurant1),此时状态还没更新,所以输出undefined。 - 首次渲染时
restaurant可能为空:父组件初始化时restaurant可能是未定义状态,直接取restaurant.place_id会导致报错,后续API请求失败,restaurant1保持初始空数组。 - API返回结构可能不匹配:Place Details API默认返回单个地点对象,而非数组,你用
res1.data.results接收会拿到undefined。
修复步骤
正确处理异步状态的日志输出
要么在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]);添加空值判断,避免首次渲染报错
在执行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]); // ...其他代码 }调整渲染逻辑匹配API返回结构
Place Details API返回的是单个对象,不需要用map遍历,直接判断状态存在后渲染:// 替换原来的map部分 <div> {restaurant1?.formatted_phone_number && ( <div>{restaurant1.formatted_phone_number}</div> )} </div>
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

