如何在不渲染任何组件的函数中使用 React.useContext ?

Men*_*nas 5 reactjs react-context

我需要获取在特定事件上调用的函数内而不是渲染器内的上下文的当前值。

例子:

logCurrentTheme.js

import React, { useContext } from 'react';
import {ThemeContext} from "./ThemeContext";
// ThemeContext is a context created by React.createContext()

function logCurrentTheme() {
  const context = useContext(ThemeContext);
  console.log(context.themeColor)
}
export {logCurrentTheme};
Run Code Online (Sandbox Code Playgroud)

在我的其他一些组件中

//...
import {logCurrentTheme} from "./logCurrentTheme.js";
//...
const someComponent () => {
  return(
    <Button onClick={logCurrentTheme} title="Log Current Theme"/>
  );
}
Run Code Online (Sandbox Code Playgroud)

上面的例子编译成功,但是一旦单击按钮就会抛出错误:

无效的挂钩调用。钩子只能在函数组件体内调用

我知道这是一个“函数”而不是“函数组件”。但我还能怎样做呢?

编辑:

基于@tudor's 答案的工作示例

LogContextButton.js

import React from "react";
import { useContextHelper } from "./ContextHelper";

export const LogContextButton = props => {
  var { logCurrentContextValue } = useContextHelper();
  return <button onClick={logCurrentContextValue}>{props.children}</button>;
};
Run Code Online (Sandbox Code Playgroud)

ContextHelper.js

import { useContext } from "react";
import { Context } from "./Context";

export const useContextHelper = () => {
  const currentValue = useContext(Context);
  const logCurrentContextValue = () => console.log(currentValue);
  return { logCurrentContextValue };
};
Run Code Online (Sandbox Code Playgroud)

tud*_*ely 4

您应该创建一个返回该logCurrentTheme函数的钩子:

export const useThemeHelper() {
  const {themeColor} = useContext(ThemeContext);
  
  const logCurrentTheme = () => console.log(themeColor);
  return {logCurrentTheme};
}

...

// and in your component: 
const SomeComponent () => {
  const {logCurrentTheme} = useThemeHelper();
  return(
    <Button onClick={logCurrentTheme} title="Log Current Theme"/>
  );
}
Run Code Online (Sandbox Code Playgroud)

您不能在另一个钩子或组件之外使用一个钩子。

  • 您需要在上下文*包装*的组件中使用钩子。codesandbox 链接使用上下文外部的钩子(在使用上下文的组件中) - 您需要将其移动到该组件的子组件之一中,或者将上下文移动为父组件。 (2认同)