not able to fetch data through api in material table react

旧巷老猫 提交于 2021-01-28 00:20:08

问题


I am trying to fetch data throught api in material react table but its showing me an error as follows Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app

code is mentioned below:

    import React, { Component } from 'react';
    import MaterialTable from "material-table";
    import withStyles from "@material-ui/core/styles/withStyles";
    import { makeStyles } from '@material-ui/core/styles';

    import ReactTable from 'react-table'
    import api from '../../api'

    import { Button } from 'react-floating-action-button'

    import "@fortawesome/fontawesome-free/css/all.min.css";
    import "bootstrap-css-only/css/bootstrap.min.css";
    import "mdbreact/dist/css/mdb.css";

    import {
    MDBBtn,
    } from "mdbreact";

    import "react-table/react-table.css";

    import styled from 'styled-components'

    import 'react-table/react-table.css'
    import { whiteColor } from 'assets/jss/material-dashboard-react';
    import { createSourceConfiguration } from '../../components/UserForm/SourceDatasetSelection';
    import { grayColor } from 'assets/jss/material-dashboard-react';



    const styles = {
                     cardCategoryWhite: {
        color: "rgba(255,255,255,.62)",
        margin: "0",
        fontSize: "14px",
        marginTop: "0",
        marginBottom: "0"
        },
      cardTitleWhite: {
      color: "#FFFFFF",
      marginTop: "0px",
      minHeight: "auto",
      fontWeight: "300",
      fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif",
      marginBottom: "3px",
      textDecoration: "none"
    }
   };

    class MoviesList extends Component {

      constructor(props) {
        super(props)
        this.state = {
            movies: [],
            columns: [],
            isLoading: true,
         }
     }

     componentDidMount = async () => {
        this.setState({ isLoading: true })

        await api.getAllMovies().then(movies => {
            this.setState({
                movies: movies.data.data,
                isLoading: false,

              })
          })
      }



     render() {



    const { movies, isLoading } = this.state
        console.log('TCL: Configuration List -> render -> movies', movies)
       // const { movies, isLoading } = this.state


    const [state, setState] = React.useState({


     columns: [
      {
        title: "Dataset Name",
       // field: "dataset",
        accessor: 'configname',
       // type: "String",

         headerStyle: { fontSize: 20,backgroundColor:grayColor},
        cellStyle: {fontSize: 18},

        }
      ]

     });
        return (
       <div style={{ maxWidth: "100%" }}>
         <MaterialTable
        title=''
        columns={state.columns}
        data={state.data}


          editable={{
           onRowAdd: newData =>
            new Promise(resolve => {
              setTimeout(() => {
                resolve();
                const data = [...state.data];
                data.push(newData);
                setState({ ...state, data });
              }, 600);
            }),
            onRowUpdate: (newData, oldData) =>
            new Promise(resolve => {
              setTimeout(() => {
                resolve();
                const data = [...state.data];
                data[data.indexOf(oldData)] = newData;
                setState({ ...state, data });
              }, 600);
            }),
            onRowDelete: oldData =>
             new Promise(resolve => {
              setTimeout(() => {
                resolve();
                const data = [...state.data];
                data.splice(data.indexOf(oldData), 1);
                setState({ ...state, data });
              }, 600);
            })
           }}



         />
       </div>
      );

    }
  }

  export default MoviesList
  //export default withStyles(styles)(Dataset);

回答1:


This error shows that you are trying to access hooks inside your class component :

MoviesList

you can not use any hooks inside class based component you need to create functional component for use of

Official doc

import React , { useState, useEffect } from 'react';

class MoviesList = () => {

const [movies,setMovies] = useState([]);
const [columns,setColumns] = useState([]);
const [isLoading,setIsLoading] = useState(false);


useEffect(async ()=> {

  setIsLoading(true)

  await api.getAllMovies().then(movies => {

        setMovies(movies.data.data);

        setIsLoading(false);

      })
} , [])

.... your logic     
}

export default MoviesList



回答2:


You can use the following ways

1) import useEffect for hooks

import React , { useState, useEffect } from 'react';

2) use the following way

useEffect(async()=>{ code... },[]); 

this code act on componentDidMount

you can use the conditions inside Square brackets '[]'

like as any change data from the list

useEffect(async()=>{
   // check the onother variable is updated or not
},[list]);

You learn more about React hooks here: React Doc




回答3:


import React, { Component, useState, useMemo } from 'react';
import Table, { StylesSimple, SelectColumnFilter, NumberRangeColumnFilter } from 
                                                             '../Tables/TableSimple';
import {GetCompanyRequesteddata } from '../APICalls/dbCompany';

 var config = { "Access-Control-Allow-Origin": "*" }
 export class CompanySearch extends Component {
              constructor(props) {
    super(props);
    this.state = {
        isLoading: false,
        requestedData: [],
        totalPageCount: 0,
        defaultPageSize: 10,
        pagereset: false,
    };

fetchData = (state, instance) => {

    this.setState({ isLoading: true });        
    const pasdata = {            
        pageIndex: state.pageIndex,
        pageSize: state.pageSize,
    };
    GetCompanyRequesteddata(config, pasdata, (res) => {
        this.setState({ requestedData: res.data.basicCompanyDataList, isLoading: false, defaultPageSize: state.pageSize, totalPageCount: res.data.totalPageCount, pageIndex: state.pageIndex });
    },
        (err) => {

        });
}

render() {

    return (
           //you may have other components here     

                    <div className="container-fluid">
                        <StylesSimple>
                            <Table
                                data={this.state.requestedData || []}
                                columns={columns}
                                onFetchData={this.fetchData}
                                loading={this.state.isLoading}
                                pageCount={this.state.totalPageCount}
                                skipPageReset={this.state.pageReset}
                            />
                        </StylesSimple>
                    </div>

                </div>
            </div>
        </div >);
   }
 } }

const columns = [
{
    Header: 'RowId',
    accessor: (row, i) => i + 1,
    width: 150,
    maxWidth: 150,
    minWidth: 150
},
{
    Header: 'Company',
    columns: [
        {
            Header: 'Name',
            accessor: 'companyName',
            aggregate: 'count',
            Aggregated: ({ cell: { value } }) => `${value} Names`,
            width: 250,
            maxWidth: 250,
            minWidth: 250

        },
        {
            Header: 'Number',
            accessor: 'companyNumber',
            // Use our custom `fuzzyText` filter on this column
            filter: 'fuzzyText',
            // Use another two-stage aggregator here to
            // first count the UNIQUE values from the rows
            // being aggregated, then sum those counts if
            // they are aggregated further
            aggregate: 'uniqueCount',
            Aggregated: ({ cell: { value } }) => `${value} Unique Names`,
            width: 150,
            minWidth: 100,
            maxWidth: 400,
        },
     ],
  },],

web api call in separate javascript file which i have placed in
import {GetCompanyRequesteddata } from '../APICalls/dbCompany';

export async function GetCompanyRequesteddata(config, payload, callback, errorcallback) {
    await axios({
        method: 'post',
        url:  'api/v1/companydata/GetCompanyRequestedData',
        data: JSON.stringify(payload),
        headers: {
            'secret-key': 'your secret key',
            'Content-Type': 'application/json'
        }
    })
        .then(res => {
            if (callback !== null) {
                callback(res)
            }
        }).catch(err => {
            if (errorcallback !== null) {
                errorcallback(err);
            }
        })
}                        

actual table I have placed in separate javascript file called TableSimple and exported as functional component

function Table({ columns, data, onFetchData, loading, pageCount: controlledPageCount, skipPageReset }) {
    const [filterInput, setFilterInput] = useState('');
    const filterTypes = React.useMemo(
        () => ({
            // Add a new fuzzyTextFilterFn filter type.
            fuzzyText: fuzzyTextFilterFn,
            // Or, override the default text filter to use
            // "startWith"
            text: (rows, id, filterValue) => {
                return rows.filter(row => {
                    const rowValue = row.values[id]
                    return rowValue !== undefined
                        ? String(rowValue)
                            .toLowerCase()
                            .startsWith(String(filterValue).toLowerCase())
                        : true
                })
            },
        }),
        []
    )
    const defaultColumn = React.useMemo(
        () => ({
            // Let's set up our default Filter UI
            Filter: DefaultColumnFilter,
            minWidth: 30,
            width: 50,
            maxWidth: 400,
        }),
        []
    )


    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        prepareRow,
        page,
        canPreviousPage,
        canNextPage,
        pageOptions,
        pageCount,
        gotoPage,
        nextPage,
        previousPage,
        setPageSize,

        state: { pageIndex, pageSize },
    } = useTable(
        {
            columns,
            data,
            initialState: { pageIndex: 0 },
            manualPagination: true,
            pageCount: controlledPageCount,
            defaultColumn,
            filterTypes,                   
            disableMultiSort: true,
            ***autoResetPage: skipPageReset,***
        },
        useFilters,
        useGroupBy,
        useSortBy,
        useExpanded, 

most important issue to be remember for server side data fetch is autoResetPage: skipPageReset

if you don't manage it by controlling {this.state.pageReset} it may call the fetchData twice as a result you would see same page data



来源:https://stackoverflow.com/questions/59834837/not-able-to-fetch-data-through-api-in-material-table-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!