为啥我不能将其转换为自定义的 React 钩子?

Posted

技术标签:

【中文标题】为啥我不能将其转换为自定义的 React 钩子?【英文标题】:Why can't I convert this to a custom React hook?为什么我不能将其转换为自定义的 React 钩子? 【发布时间】:2022-01-22 10:58:40 【问题描述】:

我的 React 应用程序中有一个薄的“服务层”,我用它来将尽可能多的业务逻辑推送到其中,并保持我的组件干净。

我一直为此使用普通函数 - 传入参数并执行所有步骤(读取/写入数据、格式化内容等)

但是,既然我已经对钩子更加熟悉了,我想知道是否可以将这些函数视为钩子,以使我的生活更轻松。例如,我希望能够在需要时从该服务层访问存储在上下文中的用户对象。

像这样:

import  useContext  from "react";

import  AppContext  from "../component/global/app_context";

const Save = async link => 
    let  user  = useContext(AppContext); //bombs on this line!
    
    //...do stuff...
    
    return true;
;

export default Save;

然后我会这样称呼它:

const onEditSave = async link => 
    let updateRes = await Save(link);
    ...do other things...redirect, etc.
;

我不断收到可怕的“只能在函数组件的主体内部调用 Hooks”错误,所以我自然是做错了。我只是不明白为什么这个函数不能转换为钩子。我将如何使用它?这是一个愚蠢的想法吗?如果它愚蠢的,我可以拉用户并将其传递给这个函数......只是我这样做了很多,把它放在组件中似乎很乏味和毫无意义自己。

除了用于显示 React 组件的方法之外,还有更简单的方法可以从普通函数访问上下文值吗?

【问题讨论】:

你应该编辑你的问题,一个有很多问题。您的一些问题是基于事实的(例如关于从普通函数访问上下文值的问题),但其他问题是基于意见的(“这是一个愚蠢的想法吗?”)。专注于基于事实的问题。对于钩子部分,我认为这个答案可能会有所帮助:***.com/a/65982894/10473393。对于“访问上下文值”部分,可能会读取“依赖注入”,这可能会有所帮助(注意:useContext 是 React 上的一个钩子) @AlexanderSantos 欣赏它,但我认为它仍然很短且易于理解。您引用的帖子虽然......不太清楚。似乎暗示我需要将它作为一个标签而不是一个函数来引用,这是行不通的。 我很确定 hooks 不能是 async 函数,如果可以的话,我不认为 React 函数组件可以是 async 函数 这肯定是简短而简单的,但它可能会导致不同的答案(而不是基于事实的答案)并且都是正确的。给它一个焦点将帮助人们回答它并帮助未来的搜索者。关于我的评论,基本上它的意思是,由于 useContext 是一个钩子,你真的无法在组件层之外使用它(你从拉动用户和传递的想法完全没问题)。我建议搜索 DI 并推荐这个答案,因为这些原则可以帮助您为您的应用程序提供单一职责。了解可能会有所帮助 【参考方案1】:

你当然可以做你想做的事!只是你需要编写一个自定义钩子。你可以在函数组件中调用 React 钩子在其他钩子中。

一种常见的模式是从您的自定义钩子返回函数,该函数使用来自其他钩子的值。

在您的情况下,我认为最好的方法是编写一个自定义挂钩,让您可以访问您创建的AppContext,以及其他“实用程序”。

类似的东西。

// Inside component/global/app_context
import React,  useContext  from "react";

const AppContext = React.createContext()

const useAppContext = () => 
    const context = useContext(AppContext);
  
    function saveUser() 
        // ...do stuff with appContext.user ...
    

    return 
      ...context,
      saveUser,
    


export default useUserContext;

然后你可以像这样访问它:

const MyComponent = () => 
    const user, saveUser = useAppContext()
    //...rest of component

你可以用这种模式走得很远。这么大的力量!

【讨论】:

啊。哈!这就是我所追求的——与我已经得到的相比,这是一个轻微的句法延伸……只是不知道如何构建它。我会试一试!谢谢!

以上是关于为啥我不能将其转换为自定义的 React 钩子?的主要内容,如果未能解决你的问题,请参考以下文章

我可以为自定义挂钩提供 react-hooks/exhaustive-deps 吗?

如何使用反冲为自定义钩子编写测试代码

如何将 dmesg 时间戳转换为自定义日期格式?

如何使用 react-hooks-testing-library 测试自定义 async/await 钩子

当 minifyEnabled 为 true 时,如何将 JSON 字符串转换为自定义对象?

如何将时间字符串转换为自定义日期格式?