在React和Redux Toolkit中,当API调用被拒绝时,如何隐藏spinner或loader?

2w2cym1i  于 2023-10-19  发布在  React
关注(0)|答案(1)|浏览(138)

我在React项目中使用了Redux Toolkit。我想隐藏<Error/>组件内的spinner.png图像,我想在isLoading状态更改为false时隐藏它。当API调用被拒绝时,isLoading State变为false。我在TopMenuSlice中将isLoading设置为false,redux devtools也显示isLoading状态已更改为false,但当我检查Loading组件中的相同状态时,它显示为true,并且由于spinner.png图像即使在拒绝的情况下也会继续显示。我不知道发生了什么。请帮帮我
TOPMENU.JSX

import React, { useEffect } from "react";
import "./topmenu.css";
import { useDispatch, useSelector } from "react-redux";
import { fetchTopMenu } from "../../../store/features/homepage/topmenu/TopMenuSlice";
import Loading from "../../others/loading/Loading";
import Error from "../../others/error/Error";

const TopMenu = () => {
  const dispatch = useDispatch();
  const { topmenuItems, isError, isLoading, isLoadingImage } = useSelector(
    (state) => state.topmenuReducer
  );
  console.log(isLoading);
  console.log("component rendered");

  useEffect(() => {
    dispatch(fetchTopMenu());
  }, []);

  if (isLoading) {
    console.log(isLoading);
    return (
      <Loading
        topmenu="topmenu"
        isLoading={isLoading}
        isLoadingImage={isLoadingImage}
      />
    );
  }

  if (isError) {
    return <Error isError={isError} />;
  }

  return (
    <>
      <div className="dvTopMenu">
        <div className="container-fluid">
          <div className="d-flex overflow">
            {topmenuItems &&
              topmenuItems.map((item) => {
                const { id, img, title } = item;
                return (
                  <div key={id} className="col text-center me-3">
                    <a href="">
                      <img src={img} alt={title} />
                    </a>
                    <p className="menu-title">{title}</p>
                  </div>
                );
              })}
          </div>
        </div>
      </div>
    </>
  );
};

export default TopMenu;

LOADING.JSX

import React, { useEffect } from "react";
import "./loading.css";

const Loading = ({ topmenu, isLoadingImage, isLoading }) => {
  console.log("isLoading redndred");
  console.log(isLoadingImage);
  return (
    <>
      <div className="dvLoading my-3 text-center">
        <div className="container-fluid">
          <div className="row">
            <div className="col-12 py-3">
              <img
                className="spinner"
                src={isLoading && isLoading === true ? isLoadingImage : ""}
                alt=""
              />
              <p className="text-capitalize">
                Please wait we are Loading
                <b className="d-block text-uppercase">{topmenu}</b>
              </p>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Loading;

ERROR.JSX

import React from "react";

const Error = ({ isError }) => {
  return (
    <>
      <div className="dvError my-3 text-center">
        <div className="container-fluid">
          <div className="row">
            <div className="col-12 py-3">
              <img
                className="spinner"
                src="https://static.wixstatic.com/media/2c0034_280b36bae7e24fdf9132a5d010c02061~mv2.png"
                alt=""
              />
              <p className="text-capitalize">
                Whoops, We apologize for the inconvenience.
                <b className="d-block text-uppercase">{isError}</b>
              </p>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Error;

TOPMENUSLICE.JS

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { baseURL } from "../../../../api/baseUrl";

const url = "topmenu";

const initialState = {
  topmenuItems: [],
  isLoading: false,
  isError: null,
  isLoadingImage: `https://static.wixstatic.com/media/2c0034_280b36bae7e24fdf9132a5d010c02061~mv2.png`,
};

export const fetchTopMenu = createAsyncThunk(
  "topmenu/fetchTopMenu",
  async () => {
    const response = await fetch(`${baseURL}/${url}`);
    if (!response.ok) {
      console.log("TOPMENU NOT FOUND.......");
      throw new Error("TOPMENU NOT FOUND");
    }
    const data = await response.json();
    return data; // Return the data to be used as the payload in fulfilled action
  }
);

export const topMenuSlice = createSlice({
  name: "topmenu",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchTopMenu.pending, (state) => {
        state.isLoading = true;
        state.isLoadingImage = `https://static.wixstatic.com/media/2c0034_280b36bae7e24fdf9132a5d010c02061~mv2.png`;
        state.isError = null;
        console.log("pending");
      })
      .addCase(fetchTopMenu.fulfilled, (state, { payload }) => {
        state.topmenuItems = payload;
        state.isLoading = false;
        state.isLoadingImage = ``;
        state.isError = null;
        console.log("success");
      })
      .addCase(fetchTopMenu.rejected, (state) => {
        state.isLoading = false;
        state.isLoadingImage = ``;
        state.isError = "An error occurred while fetching data";
        console.log("rejected");
        console.log(state);
      });
  },
});

// export const { setTopmenu, setLoading, setError } = topMenuSlice.actions;
export default topMenuSlice.reducer;
mf98qq94

mf98qq941#

问题是我正在寻找加载组件而不是错误组件。我在错误组件中添加了检查。下面是编辑后的代码,现在运行良好。
TOPMENUSLICE.js

const initialState = {
  topmenuItems: [],
  isLoading: false,
  isError: null,
//remove isLoadingImage
};

.addCase(fetchTopMenu.pending, (state) => {
        state.isLoading = true;
        // remove isLoadingImage 
        state.isError = null;
        console.log("pending");
      })
      .addCase(fetchTopMenu.fulfilled, (state, { payload }) => {
        state.topmenuItems = payload;
        state.isLoading = false;
        // remove isLoadingImage 
        state.isError = null;
        console.log("success");
      })
 .addCase(fetchTopMenu.rejected, (state) => {
        state.isLoading = false;
        // remove isLoadingImage 
        state.isError = "topmenu";
        console.log("rejected");
        console.log(state);
      });

ERROR.JSX

<div className="col-12 py-3">
              {!isError && (
                <img
                  className="spinner"
                  src="https://static.wixstatic.com/media/2c0034_280b36bae7e24fdf9132a5d010c02061~mv2.png"
                  alt=""
                />
              )}
              <p className="text-capitalize">
                Whoops, We apologize for the inconvenience. An error occurred
                while fetching
                <b className="d-block text-uppercase">{isError}</b>
              </p>
            </div>

LOADING.JSX

const Loading = ({ topmenu }) => {
  console.log("isLoading redndred");
  // console.log(isLoadingImage);
  return (
    <>
      <div className="dvLoading my-3 text-center">
        <div className="container-fluid">
          <div className="row">
            <div className="col-12 py-3">
              <img
                className="spinner"
                src="https://static.wixstatic.com/media/2c0034_280b36bae7e24fdf9132a5d010c02061~mv2.png"
                alt=""
              />
              <p className="text-capitalize">
                Please wait we are Loading
                <b className="d-block text-uppercase">{topmenu}</b>
              </p>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Loading;

相关问题