Invalid hook call issue solved when configuring with Lerna, SSR and react-redux v7.1.0 (connectAdvanced.js)

Maxim Andrews
3 min readAug 6, 2019
The KRA framework logo

While developing KRA framework I got an error of Invalid hook call . I suppose if you came to this story you got it too.

In my setup essential components to the error are Lerna, react, react-dom, redux and react-redux specifically of version 7.1.0.

The actual react error states:

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
at invariant (/Users/maxim/setup-app-suite/packages/setup-app-templates/templates/react-redux-thunk-router/node_modules/react/cjs/react.development.js:85:0)
at resolveDispatcher (/Users/maxim/setup-app-suite/packages/setup-app-templates/templates/react-redux-thunk-router/node_modules/react/cjs/react.development.js:1470:0)
at useMemo (/Users/maxim/setup-app-suite/packages/setup-app-templates/templates/react-redux-thunk-router/node_modules/react/cjs/react.development.js:1524:0)
at ConnectFunction (/Users/maxim/setup-app-suite/packages/setup-app-templates/templates/react-redux-thunk-router/node_modules/react-redux/es/components/connectAdvanced.js:116:28)
at processChild (/Users/maxim/setup-app-suite/packages/setup-app-ssr/node_modules/react-dom/cjs/react-dom-server.node.development.js:2888:14)
at resolve (/Users/maxim/setup-app-suite/packages/setup-app-ssr/node_modules/react-dom/cjs/react-dom-server.node.development.js:2812:5)
at ReactDOMServerRenderer.render (/Users/maxim/setup-app-suite/packages/setup-app-ssr/node_modules/react-dom/cjs/react-dom-server.node.development.js:3202:22)
at ReactDOMServerRenderer.read (/Users/maxim/setup-app-suite/packages/setup-app-ssr/node_modules/react-dom/cjs/react-dom-server.node.development.js:3161:29)
at Object.renderToString (/Users/maxim/setup-app-suite/packages/setup-app-ssr/node_modules/react-dom/cjs/react-dom-server.node.development.js:3646:27)
at processMethod (/Users/maxim/setup-app-suite/packages/setup-app-ssr/lib/SSRMiddleware.js:70:41)

The issue starts when you upgrade react-redux from 6.0.1 to 7.1.0 because react-redux team started utilizing some react-dom components.

Therefore, when you bundling your SSR code with webpack it copies both react and react-dom to your output file. This is one copy of react and react-dom. The other copy is the one you actually require to execute your ReactDOMServer.renderToString.

The solution

Instead of bundling both react and react-dom with the rest of your SSR code, you need to keep require statements to include those at the time of execution from the same place you includeReactDOMServer.renderToString.

To do that you have to configure externals in your webpack.config.js to exclude both full react and react-dom libraries from the bundle, but leave require('react') and require('react-dom') when building code for SSR:

node: false,
target: 'node',
externals: [ 'react', 'react-dom' ],

The actual implementation for my framework is here.

Also, make sure you include your ReactDOMServer.renderToString from the same place you include your react and react-dom.

In my case to renderToString I rely on one of my dependencies with lerna configuration. In my setup to ensure the ReactDOMServer is included from the same place I require react-dom/server from node_modules in the current working directory, the directory where you run your npm start or node ./index.js:

const path = require('path');
const ReactDOMServer = require(
path.join(
process.cwd(),
'node_modules',
'react-dom',
'server'
)
);

The actual implementation is here.

Don’t forget to add react and react-dom as your dependencies in package.json to have both of these libraries in your node_modules when you executing your project in production.

That’s it. Have a happy coding!

If you like my solution give me some claps and leave your happy comment below :) Thanks!

--

--

Maxim Andrews

23+ years of broad expertise in tech, Bachelor of Social Science in Management, International Business, MBA International Business