I'm currently working on a medium sized reactJS application and get the following error message after I click a button on a component:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.
How can I debug this more easily? Why doesn't reactJS give me a specific component name where this rule was violated?
How would you do it?
You can override console.warn to make it throw instead of log when the provided message matches a certain pattern. In your case, you'd do:
var warn = console.warn;
console.warn = function(warning) {
if (/(setState)/.test(warning)) {
throw new Error(warning);
}
warn.apply(console, arguments);
};
The stack trace of the error will then point to the line causing the warnings.
Actually, the best way to solve this issue is by changing some react code locally.
This pull-request specifically points out how to modify src/renderers/shared/reconciler/ReactUpdateQueue.js to get the component that illegaly sets state.
As this pull-request was already merged into the repo, it shouldn't be to long before it will be integrated into an npm version of react, one could hope.
Related
Would anyone know how to debug and fix (or mute) following warning (apparently, Mantine is dropping react-popper in next major release)?
Everything works fine, but warning is making it very hard to debug other issues.
Warning: flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.
at Popper (webpack-internal:///./node_modules/#mantine/core/esm/components/Popper/Popper.js:67:3)
at div
at eval (webpack-internal:///./node_modules/#mantine/core/esm/components/Box/Box.js:42:18)
at Popover (webpack-internal:///./node_modules/#mantine/core/esm/components/Popover/Popover.js:76:85)
at O (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:30:19811)
at SecretTextareaWithLength (webpack-internal:///./src/main/routes/Create.tsx:106:48)
at form
at div
at O (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:30:19811)
at Create (webpack-internal:///./src/main/routes/Create.tsx:291:48)
at Routes (webpack-internal:///./node_modules/react-router/index.js:920:5)
at MenuEvents (webpack-internal:///./src/main/MenuEvents.tsx:34:55)
at Router (webpack-internal:///./node_modules/react-router/index.js:854:15)
at MemoryRouter (webpack-internal:///./node_modules/react-router/index.js:767:5)
at MantineProvider (webpack-internal:///./node_modules/#mantine/styles/esm/theme/MantineProvider.js:66:3)
at App (webpack-internal:///./src/main/App.tsx:40:35)
this is a bug in mantine When using Popper. it will be fixed in the next release.
one thing you can do is hack your local react copy to add conditional logic and skip this warning.
another simple way is overwriting the console methods :
console.warn = () => {};
console.warn('warnings skipped.');
but in this case all warnings will be ignored
I have a huge number of console errors like this appearing in my app:
Warning: React does not recognize the textStyle prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase textstyle instead. If you accidentally passed it from a parent component, remove it from the DOM element.
Ideally I would fix the errors but sadly that's not possible as I'm using Styled System with Styled Components:
https://github.com/styled-system/styled-system/issues/1044
As a less than ideal workaround Id like to disable certain errors from the console for the development version of React. Can this be done?
Not sure if it matters but I'm using React Native Web.
You can override the console.warn method with your own function that filters out the warnings you want to ignore:
const consoleWarn = console.warn;
const SUPPRESSED_WARNINGS = ['arning text - I will n'];
console.warn = function filterWarnings(msg, ...args) {
if (!SUPPRESSED_WARNINGS.some((entry) => msg.includes(entry))) {
consoleWarn(msg, ...args);
}
};
console.warn('I\'ll appear as a warning');
console.warn('warning text - I will not');
I'm not sure which console method react is using internally, so you may need to do the same for console.info, console.log and console.error.
You can also just use the production version of react, which suppresses all warnings by default, but of course you can't pick and choose, you loose all warnings in that case.
This is brand new install - I have not put any transitions on the Alert component
To replicate the code it is simple
import React from "react";
import { Alert } from "reactstrap";
export const Index = () => {
return (
<div>
<Alert color='primary'>This is a primary alert — check it out!</Alert>
</div>
);
};
Error Msg: Please update the following components: Transition
How does one go about updating Transition or eliminating it all together?
In the event that someone comes here on after searching the question and is looking for insight this is it.
React strap (at the time of this post) uses the react-transition-group things fade in and out and menus slide up and down. After amalgamating the info on this subject here and on Github they are currently updating the library. I have finished the coding of that component by ignoring the warning.
It did not impede this iteration of that component. Happy Coding.
I have this same warning, and I fixed it changing in the index.js file, the value of <React.StrictMode> to <React.Fragment>.
Since this removes the warning, is not guaranteed that your can be bulletproof.
This issue was reported, and apparently fixed but I received the same error even with the updated source code. It's more than just the error as well - it can cause components to re-render
Here is one github thread from the reactstrap repo about this (but there are a number of them): https://github.com/reactstrap/reactstrap/issues/1340
There are a number of issues related to this warning though.
As best I can tell it has something to do with an item in Transition.js, and I think it may have to do with a this.context call when a component is 'entering'
But, the project I encountered this issue is the first React App I'm building, and I'm not quite ready to learn the Legacy Context API, so that's just my best guess and in the end I just opted for an alternative package.
I don't have the rep to put this in a comment, so the only answers I have are:
Report the issue to the reactstrap team and wait/assist with a fix
Use an alternative package
I need some help wrapping my head around eslint react-hooks/exhaustive derps.
I ONLY want the effect to run when listenToMe has changed, but react-hooks/exhaustive derps is yelling at me to add history. This causes recursion. useEffect was React gold for me until this rule.
ESLint: React Hook useEffect has missing dependencies: 'history'. Either include them or remove the dependency array.(react-hooks/exhaustive-deps)
Can someone help me understand:
Why is it bad practice to only listen for changes you care about in useEffect?
What is the "right" way to only listen for specific changes on state change?
useEffect(() => {
if (listenToMe) {
const search = new URLSearchParams(location.search);
search.delete('q')
history.replace({ ...location, search: search.toString() });
}
}
}, [listenToMe]);
I've read through github and react, but I haven't read anything that clicks.
https://github.com/facebook/create-react-app/issues/6880
https://reactjs.org/docs/hooks-rules.html
Many others...
From the docs
It is only safe to omit a function from the dependency list if nothing in it (or the functions called by it) references props, state, or values derived from them.
The problem arises when you're using passed props or in your case, the history prop coming from a HOC or hook from react-router.
First of all, its passed as a prop, and props can inherently change.
Second of all, you're calling a history.push function. The linter doesn't know that push will always be the same function of the history class and that this function will not use any state or props itself.
The "right" way according to facebook is to move the function inside the effect, but that doesn't make sense if you're just reusing code from some file or using a function like history.push. So I think in your case the solution would be to wrap it in a useCallback with history in its own dependancy array. This is a last resort according to the devs.
Essentially, useCallback will simply return a memoized value instead of actually accessing the value and whenever the value in it's dependancy changes, there is a new callback with new memoized values.
History.push will of course always have the same identity so this somewhat of an anti-pattern.
Personally I have never had any problems passing in values like this. So I think writing a useCallback when you're just dealing with functions declared elsewhere (or any fully stable variable) is pointless and I find it reasonable to skip linting that line.
I keep the rule enabled as others have pointed out however, as its good to keep you on your toes about writing effects.
This eslint rule is only a hint useful in most situations, but in some situations you have to ignore it.
React.useEffect(()=> {
// I have some code with dependencies here but I only want to run it on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
React disabled the auto fixer
https://github.com/facebook/react/issues/15204
I installed the new devDependancies (eslint#latest and eslint-plugin-react-hooks)
npm install eslint#latest eslint-plugin-react-hooks#latest --save-dev
I tested in IntelliJ IDEA 2020.1 (EAP Build #IU-201.5985.32) and it shows the warning, but ESLint Fix does not auto add dependancies to useEffect
ESLint Warning in IntelliJ
ESLint: React Hook useEffect has a missing dependency: 'dispatch'. Either include it or remove the dependency array. If 'dispatch' changes too often, find the parent component that defines it and wrap that definition in useCallback.(react-hooks/exhaustive-deps)
VS Code has the "fix" in pre release 2.1.0-next.1, but I have not tested it.
https://github.com/microsoft/vscode-eslint/pull/814#issuecomment-587020489
https://github.com/microsoft/vscode-eslint/releases/tag/release%2F2.1.0-next.1
This does NOT answer the question, but helpfull to anyone who runs into react-hooks/exhaustive-deps auto "fix" issues.
I'm trying to write Jest tests for a React component which contains a DashJS media player. I'm using Enzyme's mount method to try and test the component, but it seems that the DashJS media player fails to mount properly.
In my componentDidMount method, I have the following code:
this.videoManager = dashjs.MediaPlayer().create();
this.videoManager.initialize(this.videoPlayer, videoUrl, true);
// Where this.videoPlayer is a reference to an HTML <video> element
this.videoManager.preload();
The last line (this.videoManager.preload();) produces the following error:
You must first call attachSource() with a valid source before calling this method thrown
When I run the component it works normally - it's only the testing I'm having issues with. I haven't been able to find any related issues/solutions online.
I'm using the following versions of each relevant package:
react: "16.2.0"
dashjs: "2.6.7"
jest: "22.3.0"
enzyme: "3.3.0"
enzyme-adapter-react-16: "1.1.1"
Any help will be appreciated!
That error implies that there was some issue with videoUrl, which caused the value passed in initialize not to be set. When preload checks that a valid source has been set, the error is thrown.
At a guess, is videoUrl an empty string in your test but non-zero length when the component is used normally?
Looking at this again, the problem is probably that you are (presumably) using JSDOM to provide the DOM for your tests, and JSDOM does not provide MediaSource or WebKitMediaSource in window. This causes dash.js to fail to initialise. dash.js should throw a capability error which can be caught using player.on('error', () => {}).
As a side note, you are providing a video object to initialize, as well as setting autoplay to true. Doing the first will cause preload do nothing since it will just load segments in to the SourceBuffer instead, which probably isn't what you wanted.