为什么在调用useQuery函数时出现 "无效钩子调用"?

问题描述 投票:1回答:1

我试图在一个自定义组件中调用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 }
javascript reactjs react-admin
1个回答
0
投票

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>
}
© www.soinside.com 2019 - 2024. All rights reserved.