【问题标题】:MOBX and react integrationMOBX 和 React 集成
【发布时间】:2022-01-07 19:29:03
【问题描述】:

在重写客户端应用程序时遇到有效的钩子错误...(升级代码)

mobx 6.3.8 mobx react 7.2.1 和 mobx-state-tree 5.0.5 反应 17.0.1 RN 0.64.3

我觉得错误就在这里。我用谷歌搜索了使用商店的代码行,它把我带到了已弃用的网站……我不知道在https://mobx.js.org/react-integration.html 网站上哪里可以找到新的处理方法……这叫什么?

import { createContext, useContext } from "react"
import { RootStore } from "./root-store"


const RootStoreContext = createContext<RootStore>({} as RootStore)

const RootStoreProvider = RootStoreContext.Provider

// hook error here? // export const useStores = () => useContext(RootStoreContext);

错误: 错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:

  1. 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 React 副本 有关如何调试和修复此问题的提示,请参阅 https://reactjs.org/link/invalid-hook-call

添加更多上下文...根存储文件

import { Instance, SnapshotOut, types } from "mobx-state-tree"

import { creatMediaPlayerModel } from "../../models/media-player"
import { createUserModel } from "../../models/user"
import { createContentModel } from "../../models/content"


export const RootStoreModel = types.model("RootStore", {
mediaPlayerStore: creatMediaPlayerModel(),
userStore: createUserModel(),
contentStore: createContentModel(),
})


export type RootStore = Instance<typeof RootStoreModel>

export type RootStoreSnapshot = SnapshotOut<typeof RootStoreModel>

【问题讨论】:

  • 这个错误究竟是什么意思?
  • 添加到主帖
  • 如果我注释掉 app.tsx rootstoreprovider 钩子错误消失
  • 尝试将自定义钩子声明为函数声明

标签: reactjs typescript react-hooks mobx mobx-react


【解决方案1】:

从该错误消息中:

钩子只能在函数组件的主体内部调用。

您不是从函数组件的主体内部调用钩子。所以你打破了钩子的规则。

根据rules of hooks,您只能从反应函数组件的顶层调用钩子。如果您不在功能组件内,则不能使用反应钩子*。

来自文档:

不要在循环、条件或嵌套函数中调用 Hooks。 在任何提前返回之前,请始终在 React 函数的顶层使用 Hooks。通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。这就是让 React 在多个 useStateuseEffect 调用之间正确保留 Hooks 状态的原因。

这意味着您需要从功能组件中调用useStores

类似:

function MyComponent() {
  const myStores = useStores()

  // render component with data from stores here
  return <>{myStore.myData}</>
}

* 例外,某种意义上,是一个可以调用其他钩子的自定义钩子。您的useStores 是一个自定义钩子。所以可以从那个自定义钩子调用useContext

但是那个自定义的钩子必须遵守与内置钩子相同的使用规则,所以所有的钩子都是从一个函数组件的主体中调用的,中间只有一个函数。

【讨论】:

  • 像这样...导出默认函数 App() { const rootStore = useStores() 而不是这个? const [rootStore, setRootStore] = useState(undefined) app.tsx.. 虽然仍然报错(不调用 setRootStore FWIW)
  • 是的。而且因为App 现在使用RootStoreContext,它还必须嵌套在该提供程序下才能使一切正常。 &lt;RootStoreProvider value={...}&gt;&lt;App /&gt;&lt;/RootStoreProvider&gt;
  • 好吧,事实证明这是一团糟……哈哈。没有解决 - 必须在其他地方
  • 也许它的嵌套模型文档显示这些设置与旧文件不同
  • mediaPlayerStore: creatMediaPlayerModel(), userStore: createUserModel(), contentStore: createContentModel(),将这些注释掉也可以消除错误
猜你喜欢
  • 2019-08-15
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
相关资源
最近更新 更多