reactjsreact-context

How to use React.useContext in a function that does not render any components?


I need to get the current value of a context inside a function that is called on a specific event rather than inside a renderer.

Example:

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};

in some other component I have

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

The example above compiles successfully but once the button is clicked it throws the error:

Invalid hook call. Hooks can only be called inside of the body of a function component

I get that this is a "function" and not a "function component". But how else can I do this?

Edit:

Working example based on @tudor's answer

LogContextButton.js

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

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

ContextHelper.js

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

export const useContextHelper = () => {
  const currentValue = useContext(Context);
  const logCurrentContextValue = () => console.log(currentValue);
  return { logCurrentContextValue };
};

Solution

  • You should create a hook which returns you that logCurrentTheme function:

    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"/>
      );
    }
    

    You cannot use a hook outside another hook or a component.