繁体   English   中英

反应如何从 function 设置上下文。无效的挂钩调用

[英]React how to set context from a function. Invalid hook call

我无法从不在组件中的 function 检索上下文值。 我收到以下异常:

未捕获(承诺)错误:挂钩调用无效。 钩子只能在 function 组件的内部调用。 这可能由于以下原因之一而发生......

我已经声明了我的上下文。

export const ErrorContext = createContext({})
export const UseErrorContext = () => useContext(ErrorContext)

在我的 App.js 中设置一个提供者

<ErrorContext.Provider value={{ errorMessage }}>
</ErrorContext.Provider>

并且喜欢像这样从 function 设置值。 但这会导致上面的异常。 这个 function 在一个单独的文件中,并从不同的组件调用。

export const MyFunction = async (id) => {
   const { errorMessage } = UseErrorContext();
   errorMessage = "SOME ERROR MESSAGE";
 }

          

您将无法以这种方式执行此操作:您不能在 React 的渲染阶段之外调用挂钩。

此外,即使您这样调用它,赋值也是局部的,不会影响上下文值。

要实现您想要的行为,您需要:

  • 一个 state 用于保存错误消息以及一个 state setter
  • 每次错误更改时,上下文值都应更改
  • 你应该从调用你的钩子的组件中获取 state setter
  • 将您的 state 设置器作为回调传递给您的异步 function

是这样的:

// context
export let ErrorContext = createContext({})
export let useErrorContext = () => useContext(ErrorContext)

// provider
let [errorMessage, setErrorMessage] = useState();
let value = useMemo(() => ({errorMessage, setErrorMessage}), [errorMessage])
<ErrorContext.Provider value={value}>
  {children}
</ErrorContext.Provider>

// component
let {setErrorMessage} = useErrorContext();


export const myFunction = async (id, setErrorMessage) => {
   setErrorMessage("SOME ERROR MESSAGE");
 }

// later, in an event:
myFunction(id, setErrorMessage);


PS:此解决方案要求您为每个错误消息执行一个提供程序,以便您可以有多个,或者您应该更改抽象。

另一个解决方案看起来像是对我自己的库的提升,但事实并非如此,只是为了展示它解决这个问题的难易程度:

yarn add -D async-states react-async-states


import {useAsyncState, createSource} from "react-async-states"

// myErrorMessage should be unique, or else the library will warn
let myErrorMessageSource= createSource("myErrorMessage");



// in your component
let {state, setState} = useAsyncState(myErrorMessageSource);
// then use the state.data to display it


// in your async function, and your component would react to it
myErrorMessageSource.setState("SOME ERROR MESSAGE");

这只是库的一个基本用例,请在选择它之前阅读文档

正如错误所说:

钩子只能在 function 组件的内部调用

我的建议是创建您的自定义挂钩

一个自定义 Hook 是一个 JavaScript function 其名称以“use”开头并且可能调用其他 Hook。

现在这是可能的

export const useMyFunction = async (id) => {
const { errorMessage } = UseErrorContext();
...
}

确保只在自定义 Hook 的顶层无条件地调用其他 Hook。

从另一个组件调用自定义挂钩时相同

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM