我试图在一个自定义组件中调用react-admin固有的useQuery()函数时,出现了前面的错误。我完全糊涂了,我也不知道该怎么办。这个错误已经很清楚了,我只是不知道该如何解决。我试着访问了错误信息中的网站,并按照说明进行了操作,但我还是没办法把它做出来。
import React, { Component } from 'react';
import FolkMe from './Folkme';
import Settings from './Settings';
import Times from './Times';
import Controller from './Controller';
import axios from "axios";
import './App.css';
import { useQuery, Loading, Error } from 'react-admin';
export default class App extends Component {
constructor(props) {
super(props);
this.audioBeep = React.createRef();
this.state = {
breakLength: Number.parseInt(this.props.defaultBreakLength, 10),
sessionLength: Number.parseInt(this.props.defaultSessionLength, 10),
timeLabel: 'Session',
timeLeftInSecond: Number.parseInt(this.props.defaultSessionLength, 10) * 60,
isStart: false,
timerInterval: null
}
this.onIncreaseBreak = this.onIncreaseBreak.bind(this);
this.onDecreaseBreak = this.onDecreaseBreak.bind(this);
this.onIncreaseSession = this.onIncreaseSession.bind(this);
this.onDecreaseSession = this.onDecreaseSession.bind(this);
this.onReset = this.onReset.bind(this);
this.onStartStop = this.onStartStop.bind(this);
this.decreaseTimer = this.decreaseTimer.bind(this);
this.phaseControl = this.phaseControl.bind(this);
this.loadData = this.loadData.bind(this);
this.submitTime = this.submitTime.bind(this);
}
onIncreaseBreak() {
if (this.state.breakLength < 60 && !this.state.isStart) {
this.setState({
breakLength: this.state.breakLength + 1
});
}
}
onDecreaseBreak() {
if (this.state.breakLength > 1 && !this.state.isStart) {
this.setState({
breakLength: this.state.breakLength - 1
});
}
}
onIncreaseSession() {
if (this.state.sessionLength < 60 && !this.state.isStart) {
this.setState({
sessionLength: this.state.sessionLength + 1,
timeLeftInSecond: (this.state.sessionLength + 1) * 60
});
}
}
onDecreaseSession() {
if (this.state.sessionLength > 1 && !this.state.isStart) {
this.setState({
sessionLength: this.state.sessionLength - 1,
timeLeftInSecond: (this.state.sessionLength - 1) * 60
});
}
}
onReset() {
this.setState({
breakLength: Number.parseInt(this.props.defaultBreakLength, 10),
sessionLength: Number.parseInt(this.props.defaultSessionLength, 10),
timeLabel: 'Session',
timeLeftInSecond: Number.parseInt(this.props.defaultSessionLength, 10) * 60,
isStart: false,
timerInterval: null
});
this.audioBeep.current.pause();
this.audioBeep.current.currentTime = 0;
this.state.timerInterval && clearInterval(this.state.timerInterval);
}
loadData(profileId){
// console.log(this.props);
const { data, loading, error } = useQuery({
type: 'getOne',
resource: 'profiles',
payload: { id: 1 }
});
console.log(data);
}
submitTime() {
let timeDoneSoFar = (this.state.sessionLength * 60) - this.state.timeLeftInSecond;
}
onStartStop() {
this.submitTime();
if (!this.state.isStart) {
this.setState({
isStart: !this.state.isStart,
timerInterval: setInterval(() => {
this.decreaseTimer();
this.phaseControl();
}, 1000)
})
} else {
this.audioBeep.current.pause();
this.audioBeep.current.currentTime = 0;
this.state.timerInterval && clearInterval(this.state.timerInterval);
this.setState({
isStart: !this.state.isStart,
timerInterval: null
});
}
}
decreaseTimer() {
this.setState({
timeLeftInSecond: this.state.timeLeftInSecond - 1
});
}
phaseControl() {
if (this.state.timeLeftInSecond === 0) {
this.audioBeep.current.play();
} else if (this.state.timeLeftInSecond === -1) {
if (this.state.timeLabel === 'Session') {
this.setState({
timeLabel: 'Break',
timeLeftInSecond: this.state.breakLength * 60
});
} else {
this.setState({
timeLabel: 'Session',
timeLeftInSecond: this.state.sessionLength * 60
});
}
}
}
render() {
this.loadData(this.props.profileId);
return (
<div className="pomodoro-clock">
<Settings
breakLength={this.state.breakLength}
sessionLength={this.state.sessionLength}
isStart={this.state.isStart}
onDecreaseBreak={this.onDecreaseBreak}
onDecreaseSession={this.onDecreaseSession}
onIncreaseBreak={this.onIncreaseBreak}
onIncreaseSession={this.onIncreaseSession}
/>
<Times
timeLabel={this.state.timeLabel}
timeLeftInSecond={this.state.timeLeftInSecond}
/>
<Controller
onReset={this.onReset}
onStartStop={this.onStartStop}
isStart={this.state.isStart}
/>
<audio id="beep" preload="auto" src="..." ref={this.audioBeep}></audio>
</div>
);
}
}
以下是错误信息
×
Error: 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
See .... for tips about how to debug and fix this problem.
▶ 4 stack frames were collapsed.
App.loadData
src/src/components/pomodoro/App.js:91
88 |
89 | loadData(profileId){
90 | // console.log(this.props);
> 91 | useQuery({
| ^ 92 | type: 'getOne',
93 | resource: 'profiles',
94 | payload: { id: profileId }
useQuery
是用来在功能组件中使用的,而不是在类组件里面使用的函数,这就是为什么你会出现这个错误。对于一个类组件,你需要使用 Query
组件。
检查 legacy component doc
在 react-admin 查询 API 部分
import { Query, Loading, Error } from 'react-admin';
...
render() {
return <Query type='getOne' resource='profiles' payload={{ id: this.props. profileId }}>
{({ data, loading, error }) => {
if (loading) { return <Loading />; }
if (error) { return <Error />; }
return (
<div className="pomodoro-clock">
<Settings
breakLength={this.state.breakLength}
sessionLength={this.state.sessionLength}
isStart={this.state.isStart}
onDecreaseBreak={this.onDecreaseBreak}
onDecreaseSession={this.onDecreaseSession}
onIncreaseBreak={this.onIncreaseBreak}
onIncreaseSession={this.onIncreaseSession}
/>
<Times
timeLabel={this.state.timeLabel}
timeLeftInSecond={this.state.timeLeftInSecond}
/>
<Controller
onReset={this.onReset}
onStartStop={this.onStartStop}
isStart={this.state.isStart}
/>
<audio id="beep" preload="auto" src="..." ref={this.audioBeep}></audio>
</div>
)
}}
</Query>
}