简体   繁体   English

在控制台中获取未定义 - React.js

[英]Getting Undefined in console - React.js

So, the request is returning the JSON file.因此,请求返回 JSON 文件。 But when in console it is saying 'Undefined' and I do not know why.但是在控制台中它说“未定义”,我不知道为什么。

So the button when clicked will send the results from my request from the google Place API;因此,单击该按钮将发送我从 google Place API 请求的结果; which contains the place_id needed to make the call to the Place Details API to the Info component.其中包含调用 Place Details API 到 Info 组件所需的 place_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)} />

So, this works the way I think it does (Sorry, I am new to React)所以,这按照我认为的方式工作(抱歉,我是 React 的新手)

Here's the InfoPopup component这是 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) //This is getting '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')
  )
}

I think the problem is on the first render, there's no ID being passed.我认为问题出在第一次渲染上,没有传递 ID。 But I do not know how to work around it.但我不知道如何解决它。 Any help would be appreciated.任何帮助,将不胜感激。

Looking at this block of code:查看这段代码:

 const fetchRestaurants1 = async () => {
    const res1 = await axios.get(URL)
    setRestaurant1(res1.data.results);
  }

useEffect(() => {
      fetchRestaurants1()
      console.log(restaurant1) //This is getting 'Undefined' 
  }, [id]);

You're awaiting the result of the GET call, which is good, because it allows you to set state in the next line after waiting for the response.您正在等待 GET 调用的结果,这很好,因为它允许您在等待响应后在下一行中设置 state。

The problem: when you call fetchRestaurants1() in the useEffect(), you're not waiting for that function to execute, therefore, we jump straight to the next line and console.log() restaurant1 , which is of course still blank.问题:当您在useEffect() 中调用 fetchRestaurants1()时,您并没有等待 function 执行,因此,我们直接跳到下一行和 console.log() restaurant1 ,当然它仍然是空白的。

The same issue arises with set state calls. set state 调用也会出现同样的问题。 If you do:如果你这样做:

const [value, setValue] = useState(null);

then sometime later:然后过了一段时间:

setValue(5);
console.log(value);

The value posted to console will be null, because JS doesn't want to wait for the set state call to finish before moving onto the next line, console.log(value);发布到控制台的值将是 null,因为 JS 不想在移动到下一行之前等待 set state 调用完成,console.log(value);

To fix this: make the useEffect callback async, and await the functions in which you're making your axios.get calls.要解决此问题:使 useEffect 回调异步,并等待您在其中进行 axios.get 调用的函数。 Example:例子:

  const fetchSomeData = async () => {
    const response = await axios.get(URL);
    setData(response.data);
  }

  useEffect(async () => {
      await fetchSomeData();
      /* do some stuff */
  }, []);

Of course, you still can't console.log after the set state call above.当然上面set state调用后还是不能console.log。

If you want a generalizable way to log state changes without worrying about async behavior, you can add a simple useEffect:如果您想要一种通用的方式来记录 state 更改而不用担心异步行为,您可以添加一个简单的 useEffect:

  useEffect(() => {
    console.log(value);
  }, [value]);

Where value is any state variable.其中是任何 state 变量。 Since value is in the dependency array, anytime it changes, the useEffect will fire and log the change.由于值在依赖数组中,只要它发生变化,useEffect 就会触发并记录变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM