【问题标题】:useEffect not running on refreshuseEffect 没有在刷新时运行
【发布时间】:2021-07-14 19:13:17
【问题描述】:

我正在构建的这个博客网站上的 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;

【问题讨论】:

  • 我们需要完整代码或至少部分代码,但不需要截图
  • 抱歉,已更新。

标签: reactjs fetch use-effect


【解决方案1】:

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

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

<CardItem
  src={blogs.length > 0 ? blogs[0].mainImage : ''}
  ...
/>

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

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

【讨论】:

  • 好的,我已经尝试了这两种解决方案,它们似乎都导致了我必须开始的相同问题。在初始渲染时,它们工作正常,但是当我刷新时,博客是未定义的。
  • 其实我只是删除了useState中的[],一旦我把它们放回去,这似乎工作了!
【解决方案2】:

我遇到了同样的问题,这是我的解决方法..

首先,我创建了一个加载状态,并将初始状态设置为 true。

//  const [singlePackage, setPackage] = useState([]);

    const [isLoading, setLoading] = useState(true);

然后,在 useEffect 钩子中,我将状态设置为 false 像这样..

useEffect(() => {
   axios.get(baseURL).then((response) => {
      setPackage(response.data);
    setLoading(false);
  })
}, []);

然后,我使用了一个条件,如果加载状态为真,则返回微调器,否则返回组件,如下所示...

if (isLoading) {
    return (
      <div  className="loadingContainer">
      <Loader
      type="ThreeDots"
      color="#00b22d"
      height={100}
      width={100}
       //3 secs
    />
    </div>
    )
  } else {

    return (
     // your code here
)}

我正在使用react-loader-spinner,并且只是设置了容器的样式 您可以使用...安装它。

npm install react-loader-spinner --save

容器的样式 ...

.loadingContainer{
  position: fixed;
  top: 50%;
  left:50%;
  transform: translate(-50%,50%);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2022-11-22
    • 2020-10-22
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    相关资源
    最近更新 更多