React: Hooks API - hook breaks when exported from module

Created on 18 Nov 2018  路  6Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
I wrote a hook similar to the example in the following article:
https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889

When placed in a module and imported into another package, the following is thrown:

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

I can confirm the same code (exactly the same) works when placed into the calling app and imported (i.e., import withHook from src/hooks works with the same definition for the hook, if the hook is in src/hooks/index.js instead of a node_module)

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

The transpiled module:

// index.js

import _slicedToArray from "/Users/pdeona/Desktop/react-hook-test/hooks-test/node_modules/@babel/runtime/helpers/esm/slicedToArray";
import { useEffect, useState } from 'react';
export default (function () {
  var _useState = useState(0),
      _useState2 = _slicedToArray(_useState, 2),
      state = _useState2[0],
      setState = _useState2[1];

  useEffect(function () {
    console.log('hooked');
  });
  return [state, setState];
});

The app calling the hook: (created with CRNA 2, installed React, ReactDOM @next)

import React from 'react';
import withHook from 'withHook'
import logo from './logo.svg';
import './App.css';

function App () {
  const [s, setS] = withHook()
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

What is the expected behavior?

The hook runs.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

tested on Chrome 71, server on Node 10.13.0

module package.json:

{
  "name": "withHook",
  "version": "0.0.1",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "build": "babel index.js --out-dir dist --preset env"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "react": "^16.7.0-alpha.2"
  }
}

app package.json:

{
  "name": "hooks-test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.7.0-alpha.2",
    "react-dom": "^16.7.0-alpha.2",
    "react-scripts": "2.1.1",
    "withHook": "0.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

Most helpful comment

If you follow the link in the error message, it leads to a page that explains possible causes, mentioning the workaround for npm link workflows as well.

All 6 comments

Are you using a mono-repository or npm/yarn symlink ? I'm pretty sure you have 2 instances of React in your final bundle.

  • hooks-test/node_modules/withHook/node_modules/react
  • hooks-test/node_modules/react

Inspect bundle documentation : https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size

so i was able to confirm this by checking the source-map-explorer and fix it by installing the withHook package from the tarball, which threw no errors. i guess this can be closed, as it seems to be an issue with npm/yarn symlinks.

Yeah, we have an issue for making a better error message in case this happens.

Is there a work around for local dev of packages? I'm getting this same issue with hooks in a dependency I'm also working on.

If you follow the link in the error message, it leads to a page that explains possible causes, mentioning the workaround for npm link workflows as well.

As an FYI: The aforementioned link is https://reactjs.org/warnings/invalid-hook-call-warning.html
I had two of the issues.

  • A dependency in my component library had react 15 as a dependency rather than a peer dependency. As per the link you can debug this ala npm ls react
  • For pinning a local version of your component library for development purposes, the npm link .../react method in the link indeed worked.
    Thanks @gaearon! I didn't even notice the link in the error logs at first.
Was this page helpful?
0 / 5 - 0 ratings