具有服务器端分页的数据的React-table慢useState

时间:2019-12-09 21:04:16

标签: reactjs react-table

我正在尝试使用服务器端分页和使用react-table进行过滤。

我的表格组件看起来像:

const TbodyComponent = props => {
    for (let i = 0; i < props.children[0].length; i++) {
        props.children[0][i] = React.cloneElement(props.children[0][i], { minWidth: props.style.minWidth })
    }

    return <div className="rt-tbody">{props.children}</div>
};

const TrGroupComponent = props => {
    return <div className="rt-tr-group" role="rowgroup" style={{ minWidth: props.minWidth }}>{props.children}</div>
};

const UsersTable = props => {
    const [ loading, setLoading ] = useState(false);
    const [ tblData, setTblData] = useState([]);
    const [ allToggled, setAllToggled ] = useState(false);
    const [ toggled, setToggled ] = useState(Array.from(new Array(tblData.length), () => false));
    const [ selected, setSelected ] = useState([]);

    useEffect(() => {
        const params = {
            page: 1,
            sorted: {
                id: null,
                desc: null
            },
            searchText: ""
        }
        callListApi(params)
    }, []);

    const handleToggleAll = allToggled => {
        let selectAll = !allToggled;
        setAllToggled(selectAll);
        let toggledCopy = [];
        let selectedCopy = [];
        tblData.forEach(function (e, index) {
            toggledCopy.push(selectAll);
            if(selectAll) {
                selectedCopy.push(index);
            }
        });
        setToggled(toggledCopy);
        setSelected(selectedCopy);
    };

    const handleToggle = index => {
        let toggledCopy = [...toggled];
        toggledCopy[index] = !toggledCopy[index];
        setToggled(toggledCopy);
        if( toggledCopy[index] === false ){
            setAllToggled(false);
        }
        else if (allToggled) {
            setAllToggled(false);
        }
    };

    const callListApi = (params) => {
        console.log('params', params)
        setLoading(true);
        let url = APIhost + "/users";
        let options = {
            headers: {
                "Access-Control-Allow-Origin": "*",
            },
            credentials: "include"
        };

        axios.get(url, options)
            .then(response => {
                data = response.data;
                console.log("Data " + JSON.stringify(data));
                setTblData(data);
                setLoading(false);
            })
            .catch((error) => {
                setLoading(false);
                console.log("System error : " + error);
            });

        console.log("again: " + JSON.stringify(data));
    };

    const onChangePageGetData = state => {

                callListApi()

    };

    const columns = useMemo(
        () => [
            {
                Header: state => (
                    <input
                        type="checkbox"
                        checked={allToggled}
                        onChange={() => handleToggleAll(allToggled)}
                    />
                ),
                Cell: row => (
                    <input
                        type="checkbox"
                        checked={toggled[row.index]}
                        onChange={() => handleToggle(row.index)}
                    />
                ),
                className: "text-center sticky",
                headerClassName: "react-table-header-checkbox sticky",
                width: 35,
            },
            { //usual react-table stuff here to populate data
            },
            ]
    );

    return (
        <div className="component-card react-table">
                <ReactTable
                    className="-striped -highlight"
                    style={{
                        border: "none",
                        boxShadow: "none",
                        height: "470px",
                        fontSize: "0.75rem"
                    }}
                    data={tblData}
                    columns={columns}
                    showPagination={true}
                    pageSizeOptions = {[50, 100, 200, 500]}
                    defaultPageSize = {50}
                    sortable={false}
                    resizable={false}
                    TbodyComponent={TbodyComponent}
                    TrGroupComponent={TrGroupComponent}
                    manual
                    loading={loading}
                    LoadingComponent={Loading}
                    onFetchData={onChangePageGetData}
                    getTrProps={(state, rowInfo, column, instance) => {
                        if (rowInfo && rowInfo.row) {
                            return {
                                onClick: (e, handleOriginal) => {
                                    let present = selected.indexOf(rowInfo.index);
                                    let selectedCopy = selected;

                                    if (present === -1){
                                        selected.push(rowInfo.index);
                                        setSelected(selected);
                                    }

                                    if (present > -1){
                                        selectedCopy.splice(present, 1);
                                        setSelected(selectedCopy);
                                    }

                                    handleToggle(rowInfo.index);
                                },
                                style: {
                                    background: selected.indexOf(rowInfo.index)  > -1 ? "#ECECEC" : "white",
                                    color: selected.indexOf(rowInfo.index) > -1 ? "black" : "black"
                                },
                            }
                        }
                        else {
                            return {}
                        }
                    }}
                >
                    {(state, makeTable, instance) => {
                        let recordsInfoText = "";
                        const { pageRows, pageSize, page } = state;

                        if (tblData && tblData.length > 0) {
                            let totalRecords = tblData.length;
                            let recordsCountFrom = page * pageSize + 1;
                            let recordsCountTo = recordsCountFrom + pageRows.length - 1;

                            //recordsInfoText = `${recordsCountFrom}-${recordsCountTo} of ${totalRecords} users`;
                            recordsInfoText = `${totalRecords} Users`;
                        } else recordsInfoText = "No data found";

                        return (
                            <div className="main-grid">
                                {makeTable()}
                                <div className="above-table text-left">
                                    <div className="col-sm-12">
                                        <span className="records-info">{recordsInfoText}</span>
                                    </div>
                                </div>
                            </div>
                        );
                    }}
                </ReactTable>
            </div>
        </div>
    );
};

输出到控制台的数据几乎是即时的,但是setTblData花费了一些时间,之后该数据集没有响应(缓慢滚动,单击等)

有人认为这有什么问题吗?

PS。 我注意到它与返回的数据量(在我的情况下为500行和15列)和manual属性有关,该属性将告诉react-table将用于服务器端分页。

0 个答案:

没有答案