简体   繁体   中英

React Conditional Rendering - Loading Component

I am trying to call my Loading component when switching between the nav items. One each click it fetches new data so I'd like to place my Loading component there while we wait for the data to be loaded.

Where I'm confused is that I'm mapping over data to display my stories. In that map (below) do I add the ternary operator there to render the `Loading/> component? This is where I'm lost. I was trying to follow this post .

import { useState, useEffect } from "react";
import Story from "./Story";
import { useParams } from "react-router-dom";
import Masthead from "./Masthead";
import LoadingBar from "./LoadingBar";

export default function News() {
  const { section } = useParams();
  console.log("Section: ", section);

  const [error, setError] = useState(null);
  const [results, setResults] = useState(null);

  useEffect(() => {
    fetch(
      `https://api.nytimes.com/svc/topstories/v2/${section}.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr`
    )
      .then((res) => res.json())
      .then((data) => {
        setTimeout(() => setResults(data.results), 1500);
        console.log("Success ", data);
      })
      .catch((error) => {
        console.log("Error", error);
        setError(error);
      });
  }, [section]);

  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!results) {
    return <LoadingBar type={"cylon"} color={"#193152"} />; // this Loading bar is called when first fetching data, but doesn't re-rending when refetching new data
  } else {
    return (
      <>
        <Masthead />
        <ul className="stories">
          {results.map((story, index) => (        // Do I add the ternary operator here?
            <Story                             
              key={index}
              title={story.title}
              abstract={story.abstract}
              img={story.multimedia[0].url}
              alt={story.multimedia[0].caption}
              link={story.url}
            />
          ))}
        </ul>
      </>
    );
  }
}

My App.js with Router

import { BrowserRouter as Router, Route } from "react-router-dom";
import Masthead from "./components/Masthead";
import News from "./components/News";
import Header from "./components/Header";
import "./App.css";

export default function App() {
  return (
    <>
      <Header title={"The React Times"} />
      <Router>
        <Route path="/" exact component={Masthead} />
        <Route path="/news/:section" exact component={News} />
      </Router>
    </>
  );
}

and my Masthead section where I have my Nav items

import React from "react";
import { NavLink } from "react-router-dom";

var sections = [
  "arts",
  "business",
  "health",
  "home",
  "movies",
  "opinion",
  "politics",
  "science",
  "sports",
  "technology",
];

export default function Masthead() {
  return (
    <div className="masthead">
      <ul>
        {sections.map((section) => {
          return (
            <li key={section}>
              <NavLink classname="navItem" to={`/news/${section}`}>
                {section}
              </NavLink>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

I think your problem is that you're going to display the Loading Bar component whenever results is falsey. However, you don't set the results to null before you do the fetch, so it will still retain the contents from the last fetch, and the Loading Bar will never render again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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