Custom hook doesn't get updated value from context

I’m trying to use a custom hook to call a function which will be used for multiple components and for a context. However, the hook never gets the context value updated, it is always an empty array, but in the context the state used as the context value gets updated and in the components the context value is received. What is happening in here?

It seems to me that the context value is not being passed to the hook, but I don’t get why.

Here is a sample of my code:

Context:

import { createContext, useState, useEffect } from "react";
import useTest from "./useTest";

const TestContext = createContext({
  test: [],
  testContextFn: () => {}
});

export const TestProvider = ({ children }) => {
  const [testState, setTestState] = useState([]);

  const { testFn } = useTest();

  const testHandlerHandler = () => {
    const test = 1;
    setTestState((current) => [...current, test]);
    testFn();
  };

  const contextValue = {
    test: testState,
    testContextFn: testHandlerHandler
  };

  useEffect(() => {
    console.log("state: ", testState); // => gets the updated value
  }, [testState]);

  return (
    <TestContext.Provider value={contextValue}>{children}</TestContext.Provider>
  );
};

Hook:

import { useContext } from "react";

import { TestContext } from "./hooks/textContext";

const useTest = () => {
  const testCtx = useContext(TestContext);

  const testFn = () => {
    console.log("testCtx: ", testCtx.test); // => Always an empty array
  };

  return { testFn };
};

export default useTest;

Component:

const App = () => {
  return (
    <TestProvider>
      <ExampleComponent />
    </TestProvider>
  );
};



const ExampleComponent = () => {
  const testCtx = useContext(TestContext);
    
 console.log("testCtx: ", testCtx.test); // => Gets the updated value

  return <div onClick={testCtx.testContextFn}>CLICK HERE</div>;
};

Is there some kind of limitation when using custom hooks with context or did I miss something?

>Solution :

So the context can only be used in descendants of the provider, not inside your provider. So you should remove it from the provider and use it anywhere that has the Provider wrapped. Also, it is good to make a custom hook with your context and export it from the same Provider file.
Something like this:

export function useTestContext() {
  const context = React.useContext(TestContext)
  if (context === undefined) {
    throw new Error('useTestContext must be used within TestProvider')
  }
  return context
}

Leave a Reply