【问题标题】:I am getting the error Invalid hook call. Hooks can only be called inside of the body of a function component我收到错误无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用
【发布时间】:2021-08-06 01:11:30
【问题描述】:

我试图在每个答案负载上传到服务器时显示进度或加载栏,并在整个任务完成时显示成功消息?这是我的代码,但我收到错误消息Invalid hook call. Hooks can only be called inside of the body of a function component.

还要注意getOfflineSavedAnswers 是一个导入函数,因此我不能在此处将其设置为函数。

export default function UploadReport(type) {
    const [success, setSuccess] = useState(false) 

    useEffect(() => {
    getOfflineSavedAnswers(type).then(async answers => {
        if (answers && answers.length > 0) {
            try {
                for (const answer of answers) {
                    try {
                        await axios.post('/report/question/create-answer', answer)
                        .then(res => {
                            delAnswers("phcss")
                            setSuccess(true)
                        //  ts(`Answers successfully saved!`);
                        })
                        .catch(err => {
                            console.error(err);
                            delAnswers("phcss")
                            te(`Answers submission failed!`)
                        });
                    } catch (error) {
                        console.error(error);
                        delAnswers("phcss")
                        te(`Answers submission failed!`)
                    }
                }
                if(success){
                    ts(`Answers successfully submitted!`);
                }
                setSuccess(false)
            } catch (error) {
                console.error(error);
                te(`Answers submission failed!`)
            }
        }

    });
});
    return(
      success ? 'uploading ans...' : null
    )
};

此代码将由另一个类组件调用,如下所示,其中有多个任务

sendReportToServer = () => {
    UploadReport("phc", (msg, error) => {
        if (error) {
            te("Could not upload answer data");
        } else {
            ts(msg);
        }
    })
    UploadAnswer("phc", (msg, error) => {
        if (error) {
            te("Could not upload answer data");
        } else {
            ts(msg);
        }
    })
    UploadQuestion("phc", (msg, error) => {
        if (error) {
            te("Could not upload answer data");
        } else {
            ts(msg);
        }
    })
};

没有钩子,当我做export const uploadReport = async (type) => { 时它工作得很好。但是我引入了钩子,因为我想在每个答案有效负载上传到服务器时显示进度条或加载条,并在整个任务完成时显示成功消息

【问题讨论】:

  • UploadReport(type) 看起来有点像组件函数签名type 是 props 对象吗? UploadReport 应该是自定义钩子吗?如果是这样,请将其重命名为使用 use- 前缀命名约定,即 useUploadReport
  • @DrewReese 为什么?它呈现文本或 null。
  • @evolutionxbox 我同意 Drew 的观点,通常反应组件的参数,如果没有解构,被命名为 props。参数名称本身并不重要,但它确实闻起来像这样可能被称为UploadReport(type) 而不是<UploadReport/>。德鲁的好猜测。
  • @evolutionxbox 因为 linter 使用非常简单的规则来确定钩子是否被有效使用,而且它不是太亮,它只是遵循一些基本准则。 reactjs.org/docs/hooks-overview.html#building-your-own-hooks
  • 好点@DrewReese 我没有注意到缺少道具解构。

标签: javascript reactjs function async-await react-hooks


【解决方案1】:

钩子只有在 React 组件中使用时才有意义 - 即<MyComponent {...myProps}/>。它们不能在普通的 JavaScript 函数中使用(也没有意义)——例如UploadReport('phc',...).

纯 JavaScript 函数不能有状态或生命周期(无效果)。

只需在父组件中创建一个常规异步函数并更新状态。您不需要(也不能拥有)常规函数中的状态或效果。

像这样:

const MyParentComponent = (props) => {

 const [sending, setSending] = useState(false);

 const handleSendReportToServer = async () => {
    setSending(true);
    await callToSomeAsyncFunctionLikeUploadReport();
    setSending(false);
 }

 return {/* some jsx */}

}

【讨论】:

  • 以下代码有效,但我如何在其中显示进度或加载栏。我有一个导入的进度条来显示 3 个等待任务何时完成。我想显示每个等待的进度条。UploadReport 最多可以有 100 个发布请求,而其他人最多可以有 6 个。我在类组件中使用handleSendReportToServer。 ``` sendReportToServer = async () => { this.setState({ send: true }) await UploadReport("phcss");等待上传答案();等待上传问题(); this.setState({ 发送: false }) } }; ```
猜你喜欢
  • 2020-07-22
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2021-04-19
  • 1970-01-01
  • 2019-11-01
相关资源
最近更新 更多