why-did-you-render: trackExtraHooks cannot set property of #
By specifying trackExtraHooks, the following error is thrown.
NOTE: The error is only thrown when running in local machine, NOT in codesandbox.
whyDidYouRender.js:167 Uncaught TypeError: Cannot set property useSelector of #<Object> which has only a getter
at whyDidYouRender.js:167
at Array.forEach (<anonymous>)
at zn (whyDidYouRender.js:150)
at Module../src/index.js (index.js:9)
at __webpack_require__ (bootstrap:785)
at fn (bootstrap:150)
at Object.1 (styles.css?f684:43)
at __webpack_require__ (bootstrap:785)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
(anonymous) @ whyDidYouRender.js:167
zn @ whyDidYouRender.js:150
./src/index.js @ index.js:9
__webpack_require__ @ bootstrap:785
fn @ bootstrap:150
1 @ styles.css?f684:43
__webpack_require__ @ bootstrap:785
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 38
- Comments: 62 (1 by maintainers)
Commits related to this issue
- Patch for why-did-you-render See: https://github.com/welldone-software/why-did-you-render/issues/85 — committed to psychedelicious/lifelike by psychedelicious 4 years ago
I’m using CRA, and I managed to get around it by doing:
if (process.env.NODE_ENV === 'development') { whyDidYouRender(React, { trackAllPureComponents: true, trackHooks: true, trackExtraHooks: [[require('react-redux/lib'), 'useSelector']], }); }How are we able to fix this without ejecting the webpack config? I am unable to use the library as intended with this issue and IMO it shouldn’t be low priority/wontfix at all as a lot of people use CRA and will probably experience the same issue.
try using
import * as ReactRedux from 'react-redux'instead.Hey all, I got a similar error when trying to use why-did-you-render 7.0.1 with React Native 0.71.6 and react-redux 8.0.5:
Fortunately, it’s possible to fix it with the following two patches:
@welldone-software+why-did-you-render+7.0.1.patchreact-redux+8.0.5.patchHere are my files:
wdyr.jsbabel.plugin.jsDamn I messed up in my comment on how to deal with it and reversed the if statement. I’ll rewrite the comment from scratch again:
Sadly, webpack produces immutable objects when compiles es imports and exports. Currently, the only way to make it work is to use the “umd” version of the library being exported at least in
developmentmode:Yes, I should have elaborated.
I used the
patch-package:yarn add patch-package postinstall-postinstall -Dwebpack.config.jsas above, inserting'react-redux': process.env.NODE_ENV === 'development' ? 'react-redux/lib' : 'react-redux',in thealias:section just above...(modules.webpackAliases || {}),, which is at line 309 for me - don’t forget the comma!yarn patch-patch react-scripts- makes a patch which is created in automatically created directorypatches/"prepare": "patch-package"node_modulesis untouched and we have a simple way to revert the change in the future:yarn patch-package --reverse(will fail if the file has changed since it was patched, in this case can just doyarn add react-scripts --check-filesto revert it)package.json, removing the added scriptyarn remove patch-package postinstall-postinstallI can confirm that only setting the package alias to
react-redux/dist/react-redux.jsfixes the issue.trackExtraHooks: [[require('react-redux/lib'), 'useSelector']]doesn’t work, it only silences the error but you won’t get updates fromuseSelector.For people using
rescriptshere’s a copy&paste solution:@vzaidman
trackExtraHooks: [[require('react-redux/lib'), 'useSelector']],it’s work. thanks.
here is an example of how it works in practise: https://codesandbox.io/s/welldone-softwarewhy-did-you-render-with-reactredux-fc8es
notice when clicking on “same value” how there’s a “why did you render” log in sandbox’s console.
now, the sandbox uses react-redux/lib for some reason, but im not sure what’s going on under the hood there…
I believe theres no way to do it with CRA alone at the moment.
You can use: https://www.npmjs.com/package/react-app-rewired
To add alias to webpack as mentioned above.
The UMD build was removed in
react-redux@9.0so the workaround doesn’t work anymorehttps://redux.js.org/usage/migrations/migrating-rtk-2#dropping-umd-builds
yes, I’ve tried that and it works @tomekzaw , thanks for that! I’m just saying that maybe this patch on
jsx-dev-runtimeshould be merged in the source code of why-did-you-render.Not sure if this helps anyone, but I made a Gatsby plugin which accomplishes this. It seems to work well for me, and the solutions here might be transferable to another project.
https://www.npmjs.com/package/gatsby-plugin-why-did-you-render-redux
Sadly, webpack produces immutable objects when compiles es imports and exports. Currently, the only way to make it work is to use the “umd” version of the library being exported. At least in development:
Hey @chmiiller, have you tried the solution from my comment? It worked for me back then. You need to modify 2 files:
node_modules/@welldone-software/why-did-you-render/jsx-dev-runtime.jsnode_modules/react-redux/lib/exports.js@nikitaNaredi please use ``` for code blocks so it will be more readable. for example:
Has anybody gotten this to work with
@apollo/react-hooks? Attempted the approach here https://github.com/welldone-software/why-did-you-render/issues/85#issuecomment-612620664 and all the variations of importing with no luck.maybe
react-router-dom/cjs.but i wouldn’t track “useLocation”.
it sounds like a waste of time to me to be honest.
also, the way you import it here, should be the same way you import it everywhere in the project, so make sure to use “alias” or something.
It doesn’t seem possible to track react-router hooks on their dev & dev-experimental branches. I created an issue: https://github.com/ReactTraining/react-router/issues/7646
My apologies. I did have
whyDidYouRenderenabled, but my mistake was even more silly. I was using a proxied selector that wraps the one provided byreact-redux.The purpose of doing that is having your
Statedefined every time you calluseSelector. It calls the same function, only the reference is different, so it was not picked up bywhy-did-you-render. I imagine this pattern will become more widespread as Hooks get more popular.I imagine the solution for that is the same as before — importing a mutable object instead of (immutable) ECMAScript module. However, this could evolve badly if more and more modules receive special treatment from Webpack configuration.
Do you think it would be possible to have an API that accepts a reference to the augmented hook?
ECMAScript module objects are immutable, but their constituent members are not. This could allow us to have the best of two worlds — run
whyDidYouRenderon custom hooks without having to alter the Webpack configuration file.please look at this comment: https://github.com/welldone-software/why-did-you-render/issues/154#issuecomment-773905769
Reproduces for us when we tried to upgrade from Webpack4 to Webpack5 while on TS 4.1 and ES6.
I tried doing this with
msteams-react-base-component(v3.0.0), which has a cjs/esm directory. I had no luck and had to move on, which is a bummer because something is causing a 6x render.We have a workaround for
react-redux, but what about other popular libraries likereact-router-domand@material-ui/core? This workaround will only work forreact-redux.It would indeed work, but I would not suggest editing anything in node_modules. Better use one of the libraries that help you to patch CRA
but then you probably need to use
import {useSelector} from 'react-redux/lib'anywhere souseSelectorwould be tracked, no?I’m using CRA so it is managed internally.