Search code examples
javascriptreactjscreate-react-appreact-hooksreact-scripts

Custom hook factory works in project but not as npm dependency


I was attempting to factor this custom-hook-creating-factory-function out of an application into a library. I moved it into it's own project, made sure tests still passed, etc. Then to test it before I committed changes to the original project I npm install ../path/to/extracted/library and changed the import in the original project. Only now I get an invalid hook call error. Here's the built file from the library project:

import React, { createContext, useContext, useReducer } from 'react';

export default () => {
  const StateContext = createContext([{}, (() => { })]);
  const CtxProvider = ({ reducer, children, initialState = {}, }) => {
    const [state, dispatch] = useReducer(reducer, initialState);
    return React.createElement(StateContext.Provider, { value: [state, dispatch] }, children);
  };

  return [
    () => useContext(StateContext),
    CtxProvider,
  ];
};

It's a factory that returns a tuple with a custom hook that yields a context value and the reducer dispatch function, and a provider component that takes the reducer and initial state as props and provides the context. When I import it via npm like so

import customHookFactory from 'extracted-libaray-name';

I get the invalid hook call error.

When I import the exact same code copy-pasted into a local file like so:

import customHookFactory from '../utils/local-file';

I don't get the error. Huh? I'm using react-scripts 'start' from CRA to develop, and I'm assuming it's doing something to my local project files it's not doing to node_modules or vice-versa, but I don't know what.


Solution

  • Okay, figured it out after much futzing and reading the suggestions from the React error.

    I had listed React and react-dom as dependencies of my extracted library rather than a peer dependency, so they were different copies of react. Changing the extracted library to use React as a peerDependency and re-installing fixed it.