react.cache is not a function when called from an accompanying npm library
Unanswered
Rough harvester ant posted this in #help-forum
Rough harvester antOP
Hello. So in our monorepo that contains the skeleton Next.js app, and a library that we plan to publish.
It looks something like this:
We can use
I looked into the insides of
I managed to make it work (spoke too soon, EDIT below) by changing the import to
Is this the right way to do it? Thanks in advance.
EDIT: the function itself works, but not cached
It looks something like this:
├── my-lib
│ ├── a-module-that-uses-react-cache.js
│ ├── package.json (let’s call this "my-lib")
├── app
├── next.config.js
├── package.json (this Next.js app installs "my-lib")
├── pnpm-lock.yaml
└── pnpm-workspace.yamlWe can use
React.cache just fine in our Next.js app. However, once we start moving that same module to my-lib, we run into TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_1__.cache) is not a function error.I looked into the insides of
node_modules/react and compared it with node_modules/next/dist/compiled/react and found the former doesn’t have cache while the latter has. So I’m guessing Next is using its own pre-compiled version of React (canary or something).I managed to make it work (spoke too soon, EDIT below) by changing the import to
import { cache } from 'next/dist/compiled/react'Is this the right way to do it? Thanks in advance.
EDIT: the function itself works, but not cached
2 Replies
@Rough harvester ant Hello. So in our monorepo that contains the skeleton Next.js app, and a library that we plan to publish.
It looks something like this:
├── my-lib
│ ├── a-module-that-uses-react-cache.js
│ ├── package.json (let’s call this "my-lib")
├── app
├── next.config.js
├── package.json (this Next.js app installs "my-lib")
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
We can use `React.cache` just fine in our Next.js app. However, once we start moving that same module to `my-lib`, we run into `TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_1__.cache) is not a function` error.
I looked into the insides of `node_modules/react` and compared it with `node_modules/next/dist/compiled/react` and found the former doesn’t have `cache` while the latter has. So I’m guessing Next is using its own pre-compiled version of React (canary or something).
I managed to make it work (spoke too soon, EDIT below) by changing the import to `import { cache } from 'next/dist/compiled/react'`
Is this the right way to do it? Thanks in advance.
EDIT: the function itself works, but not cached
I’m guessing Next is using its own pre-compiled version of React (canary or something).Correct.
By default it is
react@canaryIf you use certain experimental features of nextjs, then it is
react@experimentali think you have to use
react@canary as a dependency here. or just expose the un-cache'd function and have your users cache them themselvesRough harvester antOP
I managed to solve it by introducing a workaround, that is "registering the cache" in root layout, and using this cache instead of React.cache in the lib. It isn’t pretty but it works. Unfortunately I can’t simply let the users cache them themselves, because there are modules that depend on submodules to be cached.
Thanks @joulev for your help.
Thanks @joulev for your help.
// root layout.tsx
import { cache } from 'react'
import { registerCache } from 'my-lib'
registerCache(cache)// my-lib
import type { cache as reactCache } from 'react';
// use this cache everywhere in the lib, instead of React cache
let cache: typeof reactCache = (fn) => fn;
/**
* Hacky workaround, remove soon when React.cache lands in stable React
* Next.js ships with its own React version that has React.cache (canary/experimental version of React).
* so React.cache works in Next.js, but not in our lib. So we need to "register" the cache from Next.js
*
* Check often: https://react.dev/reference/react/cache
*
* Once it lands, remove this
* and change to `import { cache } from 'react'`
*/
export const registerCache = (c: typeof cache) => (cache = c);