useEffect 不在刷新时运行

Dav*_*tta 6 fetch reactjs use-effect

我在我正在构建的博客网站上遇到了 useEffect 挂钩问题。我尝试从后端获取所有博客,以便我可以使用它们用最新的五个博客填充此部分。当我使用下面的代码时,useEffect 中的空数组可以防止无限量的 fetch 调用,这很棒。

但后来我遇到了一个问题,如果我刷新页面或导航回该页面,我会在第 35 行收到一条错误消息,提示“找不到未定义的 mainImage”。

我的问题是如何让 fetchCall 填充状态,甚至在刷新时也这样做,以便我仍然可以访问我需要的信息。谢谢!

import React, {useState, useEffect} from 'react';
import CardItem from './CardItem';
import './Cards.css';

function Cards() {
  const [blogs, setBlogs] = useState();

  useEffect(() => {
      fetchBlogs();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  },[]);

  const fetchBlogs = async () => {
    console.log('ok');
    const response = await fetch('http://localhost:3000/blogs');
    const data = await response.json();
    setBlogs(data);
  };


  return (
    <div className='cards'>
      <div className='header-container'>
        <img
          className='logo'
          alt='logo'
          src='https://Zi.imgur.com/MaLqLee.png'
        />
        <h1 className='cards-title'>Hot takes and hometown bias</h1>
      </div>
      <div className='cards-container'>
        <div className='cards-wrapper'>
          <ul className='cards-items'>
            <CardItem
              src={blogs.length > 0 ? blogs[0].mainImage : ''}
              text="Don't look now, but Zach Lavine officially kicks ass."
              label='Bulls'
              path='/bulls'
            />
            <CardItem
              src='https://i.imgur.com/EmVgHk2.jpg'
              text='The curious case of Mitch Trubisky apologists.'
              label='Bears'
              path='/bears'
            />
          </ul>
          <ul className='cards-items'>
            <CardItem
              src='https://i.imgur.com/ZZ5dLJU.jpg'
              text='How Did We Get Here? The Suddenly Bleak State of the Cubs.'
              label='Cubs'
              path='/cubs'
            />
            <CardItem
              src='https://i.imgur.com/MwgKmUM.jpg'
              text='Pace and Nagy: So, how much can we blame these guys?'
              label='Bears'
              path='/bears'
            />
            <CardItem
              src='https://i.imgur.com/Y2Eorvu.jpg'
              text='Thad Young: An Ode to the NBA Journeyman.'
              label='Bulls'
              path='/bulls'
            />
          </ul>
        </div>
      </div>
    </div>
  );
}

export default Cards;
Run Code Online (Sandbox Code Playgroud)

Maa*_*Dev 4

获取调用是异步的。这意味着在程序进入下一行之前不能保证它完成。

因此,blogs第一次渲染时数组将为空。您可以在 CardItem 组件中添加一个检查src,以便仅使用调用返回的值(fetch当该值可用时):

<CardItem
  src={blogs.length > 0 ? blogs[0].mainImage : ''}
  ...
/>
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用blogs数组这一事实并使用map运算符来构建一个或多个CardItems。

<ul className='cards-items'>
  {blogs.map(blog => <CardItem
    src={blog.mainImage}
    ...
  />)}
</ul>
Run Code Online (Sandbox Code Playgroud)