javascript - react : How to show Spinner & Component (at the same time) when State Changes using `useEffect`

标签 javascript reactjs react-redux react-router

我正在使用条件渲染在第一次 API 调用期间显示 spinner
date 发生变化时,如 useEffect 依赖数组,再次调用 API

问题:

如果数据获取不完整,旧数据会显示在屏幕上。
但我希望 spinner 显示旧数据,以便用户可以感知该数据正在加载。

当前的实现即条件渲染仅显示一个组件,spinnerGrid

微调器

Before Loading

网格组件 After Loading

    import React, { Component, useState, useEffect } from "react";
    import { connect } from "react-redux";
    import ApiHelper from "../../api/ApiHelper";
    import ReactDataGrid from "react-data-grid";
    import { Toolbar, Data, Filters } from "react-data-grid-addons";
    import JarvisSpinner from "../presentationalComponents/JarvisSpinner";
    import { withRouter } from "react-router-dom";
    import "../../css/styles.css";
    import "../../css/JarvisGrid.css";

    const JarvisGrid = (props) => {
      const [pagesize, setPageSize] = useState(15);
      const [data, setdata] = useState([]);
      const [filters, setFilters] = useState({
        filterfield: "Application Send",
        filtervalue: "Base",
      });
      const [sort, setSort] = useState({
        Field: "PublicOrderNumber",
        Direction: "desc",
      });
      const [loading, setloading] = useState(true);

      useEffect(() => {
        //Set data
        ReloadData();
      }, [props.uid, props.CalendarDates.fromDate, props.CalendarDates.toDate]);


      // For Loading Data using API
      const ReloadData = () => {
        ApiHelper.GetGridQueryResult(
          props.uid,
          props.filterField,
          props.filterValue,
          props.CalendarDates.fromDate,
          props.CalendarDates.toDate
        )
          .then((response) => {
            setdata(response.data.responses);
            setloading(!loading);
          })
          .catch((error) => {
            setdata([]);
            switch (error.response.status) {
              case 403:
                console.log("Error code --> " + 403);
                props.history.push("/unAuthorizedPage");
                break;
              default:
                console.log("Error String --->" + error);
            }
          });
      };

      return (
        <>
          {loading ? (
            <JarvisSpinner size="3x" />
          ) : (
            <div className="JarvisGrid">
              <ReactDataGrid
                columns={props.columns}
                rowGetter={(i) => data[i]}
                rowsCount={data.length}
                minHeight={500}
                uid={props.uid}
                enableRowSelect={null}
                enableCellSelect
                toolbar={<Toolbar enableFilter="true" />}
                onAddFilter={(filter) => {
                  setFilters({
                    filterfield: filter.column.key,
                    filtervalue: filter.filterTerm,
                  });
                }}
                onClearFilters={() =>
                  setFilters({
                    filterfield: "OrderType",
                    filtervalue: "Base",
                  })
                }
                onGridSort={(sortColumn, sortDirection) => {
                  setSort({ Field: sortColumn, Direction: sortDirection });
                }}
              />
            </div>
          )}
        </>
      );


    };
    function mapStateToProps(state) {
      return {
        CalendarDates: state.calendarDates,
      };
    }

    export default withRouter(connect(mapStateToProps)(JarvisGrid));

请注意,我使用 redux 进行状态管理和 react-router

============================================= == 实现 MwamiTovi 提供的解决方案后 现在我必须找出叠加的东西。

After implementing solution

最佳答案

这实际上很好,根据您的逻辑:

// Within your "return" statement
return (
   <>
      {loading ? ( 
        <JarvisSpinner size="3x" />   // renders if `loading === true`
        ) : (
        <div className="JarvisGrid">  // renders if `loading === false`
          <ReactDataGrid .../>
        </div>
        )
      )}
   </>
)

这就是你真正想要的:

  • 第一次,在 API 调用期间只加载 spinner

  • 数据获取(API 调用)成功后,仅显示 Grid 组件

  • 在随后的 API 调用中,呈现 spinnerGrid

让我们这样:

// Initiate `data` as `null`
// After the first time, `data` will never be `null` again
const [data, setdata] = useState(null);

// Remember, !null === true since data === null,
// So first time API call, only spinner will show up,
// Upon the next calls, !data === false, so this won't load
if (!data) {
  return <JarvisSpinner size="3x" /> ;
}

// Within your "return" statement
// After the first API, all the other API calls will do this...
return (
   {loading ? ( 
     <>
        <JarvisSpinner size="3x" />  // renders both spinner & component, `loading === true`
        <div className="JarvisGrid"> // consider placing an "overlay" onto the component
          <ReactDataGrid .../>
        </div>
     </>
    ) : (
        <div className="JarvisGrid">  // renders only component, when `loading === false`
          <ReactDataGrid .../>
        </div>
        )
    )}
)

关于javascript - react : How to show Spinner & Component (at the same time) when State Changes using `useEffect` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61101503/

相关文章:

javascript - 如何使用回调测量 JavaScript 代码的执行时间?

javascript - ReactJS 网络应用程序 : Selective Mobile Scrolling Bug

css - 如何在 Material-UI 中将 Select 组件设置为在选择其元素之一后松开其焦点状态

css - 如何在 Windows 上将 docker nginx 与 express 和 react 应用程序连接起来

react-native - React Native - "You are currently using minified code outside of NODE_ENV === "生产""

javascript - 将下载字符串作为文本文件发出

javascript - 将对象和函数转换为有效的 JavaScript 源代码?

javascript - 按钮、jquery 和模式

javascript - Angularjs:访问范围变量数组并计算平均值

reactjs - 嵌套 `combineReducers` 不允许在没有嵌套对象的情况下拥有状态