在呈现 DOM 之前加载异步数据

Load async data before rendering the DOM

仍在学习中,我无法理解如何从异步函数获取数据然后在 DOM 中显示它。

确实,我没有定义,因为 dom 在异步函数之前呈现。

我被卡住了,我的问题是如何处理这种情况?什么是好的做法?

export default function ProductCard ({ product }) {

    const { handle, title } = product.node

    const [productDetails, setProductDetails] = useState();

    const data = async () => {
        const data = await getProduct(handle)
        //console.log(data)
        setProductDetails(data);
    }

    useEffect(() => {
        data();
    }, [])

//or data();

console.log("productDetails", productDetails);


return (
    <>
       {productDetails.handle}
    </>
)


}

感谢您的帮助和支持。

你很接近。第一次渲染状态为 undefined 是正常的,因为那是你设置的初始状态,并且获取数据需要时间。所以你只需要在你还没有数据的情况下渲染一些不同的东西。你可以 return null 如果你不想渲染任何东西,或者可能是一个加载占位符:

if (productDetails) {
  return (
    <>
      {productDetails.handle}
    </>
  )
} else {
  return <div>Loading...</div>
  // or
  //return null;
}

对于你的情况,这应该足够了。但是,如果您发现自己在处理一个非常复杂的组件,总是必须检查 undefined 很麻烦,那么您可以将其拆分为两个组件。外部组件负责加载并处理未定义的可能性,内部组件仅渲染一次 undefined 不再可能:

const Parent = (props) => {
  const [productDetails, setProductDetails] = useState();

  useEffect(() => {
    const fetchData = async () => {
      const data = await getProduct(handle);
      //console.log(data)
      setProductDetails(data);
    };
    fetchData();
  }, []);

  if (productDetails) {
    return <Child {...props} productDetails={productDetails} />;
  } else {
    return null;
  }
};

const Child = ({ product, productDetails }) => {
  // Everything in here can assume productDetails exists

  return (
    <>
      {productDetails.handle}
    </>
  )
};