React:如何在状态更改时使用`useEffect`

时间:2020-04-08 13:10:42

标签: 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

3 个答案:

答案 0 :(得分:1)

我会在您的ReloadData函数中执行此操作:

const ReloadData = () => {
    setLoading(true); // HERE

    ApiHelper.GetGridQueryResult(
      props.uid,
      props.filterField,
      props.filterValue,
      props.CalendarDates.fromDate,
      props.CalendarDates.toDate
    )
      .then((response) => {
        setdata(response.data.responses);
        setloading(false); // HERE
      })
      .catch((error) => {
        setdata([]);
        setloading(false); // HERE

        switch (error.response.status) {
          case 403:
            console.log("Error code --> " + 403);
            props.history.push("/unAuthorizedPage");
            break;
          default:
            console.log("Error String --->" + error);
        }
      });
  };

答案 1 :(得分:1)

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

HTMLElement

这就是您真正想要的:

  • 第一次,在API调用期间仅加载HTMLDivElement

  • 成功获取数据(调用API)后,仅显示// Within your "return" statement return ( <> {loading ? ( <JarvisSpinner size="3x" /> // renders if `loading === true` ) : ( <div className="JarvisGrid"> // renders if `loading === false` <ReactDataGrid .../> </div> ) )} </> ) 组件

  • 在随后的API调用中,同时渲染spinnerGrid

让我们这样:

spinner

答案 2 :(得分:0)

https://www.npmjs.com/package/react-loading-overlay


检查。我相信这可以解决您的问题。

<LoadingOverlay
active={isLoading}
    spinner={Your own spinner}
    styles={{
    wrapper: {
       height: "100vh",
       overflow: "scroll"
    }
}}>
        <div>Show your content here</div>
</LoadingOverlay>