是否可以在 React 的 useEffect 中使用自定义钩子?

2024-01-08

我有一个非常基本的自定义挂钩,它接受路径并从 firebase 返回文档

import React, { useState, useEffect, useContext } from 'react';
import { FirebaseContext } from '../sharedComponents/Firebase';

function useGetDocument(path) {
    const firebase = useContext(FirebaseContext)
    const [document, setDocument] = useState(null)

    useEffect(() => {
        const getDocument = async () => {
            let snapshot = await firebase.db.doc(path).get()
            let document = snapshot.data()
            document.id = snapshot.id
            setDocument(document)
        }
        getDocument()
    }, []);

    return document
}

export default useGetDocument

然后我使用 useEffect 作为 componentDidMount/构造函数来更新状态

useEffect(() => {
    const init = async () => {

      let docSnapshot = await useGetDocument("products/" + products[selectedProduct].id + "labels/list")
      if(docSnapshot) {
        let tempArray = []
        for (const [key, value] of Object.entries(docSnapshot.list)) {
          tempArray.push({id: key, color: value.color, description: value.description})
        }
        setLabels(tempArray)
      } else {
        setLabels([])
      }

      await props.finishLoading()
      await setLoading(false)
    }
    init()
  }, [])

但是,我从“throwInvalidHookError”中得到了不变违规,这意味着我违反了钩子规则,所以我的问题是你是否不能在 useEffect 中使用自定义钩子,或者我是否做了其他错误的事情。


据我所知,组件中的钩子应该始终保持相同的顺序。并且自从useEffect有时会发生,并不是每个渲染都会破坏钩子规则 https://reactjs.org/docs/hooks-rules.html。在我看来就像你的useGetDocument没有真正的需要。

我提出以下解决方案:

  1. 保持你的useGetDocument相同。
  2. 更改您的组件以具有useEffect具有document作为依赖。

您的组件可能如下所示:

const Component = (props) => {
    // Your document will either be null (according to your custom hook) or the document once it has fetched the data.
    const document = useGetDocument("products/" + products[selectedProduct].id + "labels/list");

    useEffect(() => {
        if (document && document !== null) {
            // Do your initialization things now that you have the document.
        }
    }, [ document ]);

   return (...)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在 React 的 useEffect 中使用自定义钩子? 的相关文章

  • 我如何设计react-datepicker的样式?

    我在用着webpack 反应日期选择器并设法使用提供的 css 模块导入其 css import react datepicker dist react datepicker cssmodules css 该组件看起来不错 但现在我想让它像
  • addEventListener 通过映射调度来反应 redux

    我目前正在尝试将事件侦听器添加到我在反应中制作的应用程序 我通过连接到运行的 componentDidMount API 来做到这一点只有一次该组件已渲染 仅此而已 我的问题是我正在使用connect from react redux将我的
  • ReactTable 修复了最后一行

    我正在使用 ReactTable 最后我需要创建一些摘要 当分页存在时 它每次都应该可见 可以用react table来实现吗 我可以通过创建下一个表来部分解决这个问题 但我没有找到如何隐藏标题的方法 另一个问题是调整列宽度时 它不会应用于
  • 错误找不到“pages”目录。请在项目根目录下创建一个”

    以前我的项目设置是 public next src pages components assets next config js 这工作正常 但我将结构更改为以下 public src client next config js jscon
  • 如何聚焦反应路由器链接

    我有一个用于搜索的输入框 并且希望能够按向下键将焦点从输入移动到列表的第一个s 看来我这里的东西不起作用 因为不是实际的 DOM 节点 我能够使用它来工作 a 代替 though let Link require react router
  • 获取 JSON 中的 HTML 以在 React 组件中呈现为 HTML

    试图找出如何让链接实际呈现为链接 现在 在我从 Json 文件中读取这行文本后 React 将超链接渲染为文字文本 而不将其渲染为链接 一些数据 json about John has a blog you can read a href
  • Nextjs 无法在生产环境中的“.next”目录中找到有效的构建

    我正在 docker 中运行我的应用程序 但我的生产构建和启动脚本仅在 docker 环境中失败 虽然node env开发在docker环境下运行良好 这是我的脚本 无法进行生产构建并启动服务器 我正在使用nodemon和babel bui
  • React + Semantic-UI:在 UI MODAL 中使用表单

    在没有 React 的普通旧 Semantic UI 中 我已经能够毫无问题地将表单放入 Modal 中 使用 Semantic UI React 版本 我能够在模态中显示表单 但它并没有按照我期望的方式工作 例如 模态框显示后 模态框内的
  • 使用 nginx 在云上部署 django 和 React

    我有一个 digitalocean 服务器 并且已经使用 Gunicorn 和 nginx 部署了 Django 后端服务器 如何在同一台服务器上部署 React 应用程序 您可以构建 React 应用程序并使用 Nginx 提供其静态文件
  • 提及列表和表情符号顶部位置 (Draft.js)

    您能帮我如何将其位置从下到上更改吗 我想在文本顶部而不是底部显示提及列表 关于表情符号列表的同样问题 示例链接 https www draft js plugins com plugin emoji 你可以通过以下方式实现它position
  • 刷新或直接点击链接时找不到 React.js 页面

    我在此链接上有一个反应项目 https notchy cross 000webhostapp com https notchy cross 000webhostapp com 如果向下滚动 您会看到一个名为 产品类别 的部分 https i
  • 从 React Native Js 代码调用 Android Native UI 组件方法

    我创建了一个 CustomView SignatureView java 它扩展了 LinearLayout 以捕获 Android Native 中的签名 并创建了SignatureCapturePackage java和Signatur
  • React 中的 Reconciliation 详解

    我是 React JS 的新手 谁能准确解释和解是如何运作的 我尝试从 React 官方网站上理解它 但没有得到它 我是这样理解的 您会同意 React 使用组件使事情变得简单且更快 通过 JSX 我们可以让用户定义的组件变得更容易 一天结
  • ReactTransitionGroup 不适用于 React-redux 连接组件

    我正在开发一个更大的项目 但我创建了这个简短的示例来说明问题 如果我使用Box组件 它的工作原理 它在控制台中输出componentWillEnter and componentWillLeave当我们点击按钮时 如果我使用BoxConta
  • React - 如何在不使用构造函数的情况下访问道具

    注意 我在使用 React Native 时遇到了这个特定问题 但我想这也适用于 React 我有一个使用 React Component 构建的反应组件 我不需要设置状态 但我确实有道具 我建议的语法如下 class Header ext
  • React 设置背景颜色与状态 rgb

    所以我根据数据库的结果生成一个表 在数据库中我保留 rgb 值 例如 75 75 75 现在当我生成列表时 我想使用保存的值设置我的 td 的背景 tbody this state boxes map box i gt tr td box
  • 如何渲染变量(或 prop)内部的 jsx/html?

    const Footer gt let a b Hey b return div Some bold text a div 这只会呈现为Some bold text b Hey b 如何将粗体文本渲染为粗体 变量内容是我自己的 所以我不必担
  • 代码镜像错误:未捕获错误:扩展集中无法识别扩展值([对象对象])

    全部 我目前正在从事一个React Electron项目 该项目的目标是完成一个Markdown编辑器 当我配置codemirror 该程序报告错误说 Uncaught Error Unrecognized extension value
  • Cypress 在 Create React App 中返回 .scss 文件的 webpack 编译错误

    我正在尝试将 Cypress 添加到非常基本的 CRA 但遇到了 Cypress 无法理解 scss 文件的问题 当我跑步时npm run cypress运行测试 我收到以下错误 Error Webpack Compilation Erro
  • 如何在执行新操作时取消先前操作的执行?

    我有一个动作创建器 它会进行昂贵的计算 并在每次用户输入内容时调度一个动作 基本上是实时更新 但是 如果用户输入多个内容 我不希望之前昂贵的计算完全运行 理想情况下 我希望能够取消执行先前的计算并只执行当前的计算 没有内置功能可以取消Pro

随机推荐