我正在尝试通过材料反应表中的api获取数据,但它向我显示如下错误 无效的挂接调用。挂钩只能在功能组件的主体内部调用。可能由于以下原因之一而发生: 1.您的React和渲染器版本可能不匹配(例如React DOM) 2.您可能违反了《钩子规则》 3.您可能在同一应用程序中拥有多个React副本
代码在下面提到:
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);
答案 0 :(得分:0)
此错误表明您正在尝试访问类组件内部的钩子:
MoviesList
you can not use any hooks inside class based component you need to create functional component for use of
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
答案 1 :(得分:0)
您可以使用以下方式
1)为钩子导入useEffect
import React , { useState, useEffect } from 'react';
2)使用以下方式
useEffect(async()=>{ code... },[]);
此代码在 componentDidMount
上起作用您可以使用方括号“ []”内的条件
就像列表中的任何更改数据一样
useEffect(async()=>{
// check the onother variable is updated or not
},[list]);
您可以在此处了解有关React钩子的更多信息:React Doc
答案 2 :(得分:0)
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,
},
],
},],
我放置在单独的javascript文件中的网络api调用
从'../APICalls/dbCompany'导入{GetCompanyRequesteddata};
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);
}
})
}
我已将实际表放在名为TableSimple的单独的javascript文件中,并作为功能组件导出
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,
对于服务器端数据提取,要记住的最重要的问题是autoResetPage:skipPageReset
如果您无法通过控制{this.state.pageReset}对其进行管理,则它可能会调用fetchData两次,结果您将看到相同的页面数据