【问题标题】: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 组件的方法之外,还有更简单的方法可以从普通函数访问上下文值吗?

【问题讨论】:

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

标签: javascript reactjs ecmascript-6 react-hooks


【解决方案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
}

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

【讨论】:

  • 啊。哈!这就是我所追求的——与我已经得到的相比,这是一个轻微的句法延伸……只是不知道如何构建它。我会试一试!谢谢!
猜你喜欢
  • 2021-12-14
  • 1970-01-01
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多