garbles / why-did-you-update Goto Github PK
View Code? Open in Web Editor NEW:boom: Puts your console on blast when React is making unnecessary updates.
:boom: Puts your console on blast when React is making unnecessary updates.
Hi, I'm wondering if this works when you append new items to a list.
I have a CollectionView:
const RowList = ({ rows }) => {
return (
<div>
{rows.map(row => (
<Row
key={row.id}
id={row.id}
name={row.name}
/>
))}
</div>
);
};
Whenever I add items to the "rows" object, I want to render these rows.
By adding key={row.id}, React makes sure that components that are already rendered are not rerendered.
But unfortunately, why-did-you-update tells me that a part of the list is still the same, so I have to avoid the rerender:
RowPage.props.rows.0
deepDiff.js:38 Value did not change. Avoidable re-render!
RowPage.props.rows.1
deepDiff.js:38 Value did not change. Avoidable re-render!
etc.
Note that it gives this error on the component that contains the RowList, not on the RowList itself.
I'm wondering if the warning is correct and I should make changes to the data structure, or if why-did-you-update is giving me a false positive.
Should lodash be moved to an actual dependency instead of development one?
Any plans to bring this project back to life to make it work and make it work with React v15.5+?
componentDidUpdate will override the original method, can we use createChainedFunction to link those function?
https://github.com/garbles/why-did-you-update/blob/master/src/index.js#L27
componentWillUpdate's SpecPolicy:
https://github.com/facebook/react/blob/master/src%2Fisomorphic%2Fclassic%2Fclass%2FReactClass.js#L242-258
how mixin work with SpecPolicy.DEFINE_MANY
https://github.com/facebook/react/blob/master/src%2Fisomorphic%2Fclassic%2Fclass%2FReactClass.js#L517-L519
createChainedFunction:
https://github.com/facebook/react/blob/master/src%2Fisomorphic%2Fclassic%2Fclass%2FReactClass.js#L621-L634
https://github.com/reactjs/react-static-container
If I wrap React with why-did-you-update
I get an endless loop where it constantly appends new _reactInternalInstance._instance
checks.
We're using Relay.js which uses StaticContainer
, and I suspect that's the cause here (since you can see it appending the _store
attribute in the logs).
Somewhere after [email protected]
the createClass
is not called for function components anymore. It means that the original monkey-patch doesn't work. Today I tried to hack react-addons-perf
for the same purpose and it seems to work fine so far. For anybody who might be interested:
// whyDidYouUpdate2.js
import get from 'lodash/get';
import { deepDiff } from 'why-did-you-update/lib/deepDiff';
export default (ReactDebugTool) => {
const debugProps = {};
const _onBeforeMountComponent = ReactDebugTool.onBeforeMountComponent;
ReactDebugTool.onBeforeMountComponent = (
function (debugID, element, ...args) {
const componentName = get(element, 'type.displayName', get(element, 'type.name', ''));
if (componentName && /^[a-zA-Z0-9]+$/.test(componentName)) {
debugProps[debugID] = get(element, 'props');
}
_onBeforeMountComponent(debugID, element, ...args)
}
).bind(ReactDebugTool);
const _onBeforeUpdateComponent = ReactDebugTool.onBeforeUpdateComponent;
ReactDebugTool.onBeforeUpdateComponent = (
function (debugID, element, ...args) {
const componentName = get(element, 'type.displayName', get(element, 'type.name', ''));
if (componentName && /^[a-zA-Z0-9]+$/.test(componentName)) {
const prevProps = debugProps[debugID];
const props = get(element, 'props');
deepDiff(prevProps, props, componentName);
debugProps[debugID] = props;
}
_onBeforeUpdateComponent(debugID, element, ...args);
}
).bind(ReactDebugTool);
}
Usage:
import whyDidYouUpdate2 from './whyDidYouUpdate2';
import ReactDebugTool from 'react-dom/lib/ReactDebugTool';
import Perf from 'react-addons-perf';
whyDidYouUpdate2(ReactDebugTool);
Perf.start();
Really neat idea, I like it!
However I feel like it's not necessarily ideal in real life to have it turned on for all components.
The ignore
option is a nice one, but I'd rather have an include
option or something similar that does the opposite: Opt-in for specific components.
Typically that would help if you're concentrating on optimising a given component rather than being polluted by other components.
What do you think?
It will be nice to create typings for why-did-you-update in DefinitelyTyped
Great plugin.
I would love an option to specify if "Value did not change" messages should go through console.error
or console.warn
. In React Native, a console.error
call triggers the red error screen and kills the app.
I'm happy to implement this myself and send over a PR if you have an API in mind for user-configured settings.
Thanks
Using React Router v4, it adds the match object (https://reacttraining.com/react-router/web/api/match) to all React components. This causes why-did-you-update to do a deep diff on this object and warn even if there are no unnecessary renders.
Any ideas how to resolve this?
When you have props
with nested object which is shared between updates
const style = {height: "auto"};
...
// render
<Description text={text} style={style} />
...
// update with the reference to the same style property
<Description text={newText} style={style} />
why-did-you-update shows warning although re-render is unavoidable (style
did not change, but other props do)
Description.props.styles
"Value did not change. Avoidable re-render!"
before Object {height: "auto"}
after Object {height: "auto"}
Right now the package is normalising strings into regex values so it can use the same .test() method in shouldInlude(). I think it might give false positives because it's not an equality check anymore but it checks if the string is found in a component names. That means a string exclusion called 'Bar' will also match a component named 'FooBar'.
See also #14 for the reason why I'm opening this issue.
Hi!
when I use this package with PureComponent
such as:
import { PureComponent } from 'react';
class MyComponent extends PureComponent {
}
I'm getting a warning for every prop, while switching to Component
(without any componentShouldUpdate method) it just works as expected.
If I try to add a notifier param, it seems ignored.
The last commit on this file is from a year ago: https://github.com/garbles/why-did-you-update/blob/master/src/normalizeOptions.js As a release been made after that?
if (__DEV__) {
const { whyDidYouUpdate } = require('why-did-you-update')
whyDidYouUpdate(React, {
notifier: () => {},
})
}
Thanks
This repository is very popular (over 5k stars as of mid '17) and issues and PRs are compounding as it is no longer maintained.
There are many forks to this repo which take care of some/all of these issues. It might be a good idea to add alongside "THIS IS NOT BEING MAINTAINED" a link to one of these repositories if the fork owner is comfortable moving it forward.
If you can recommend a working fork or run one yourself please mention that here, then we can create a PR to direct users to your repository instead.
W20170107-14:20:00.841(8)? (STDERR) Error: Cannot find module './deepDiff'
W20170107-14:20:00.842(8)? (STDERR) at require (packages/modules-runtime.js:109:19)
W20170107-14:20:00.842(8)? (STDERR) at meteorInstall.node_modules.pretty-bytes.why-did-you-update.lib.index.js (packages/modules.js:24170:17)
W20170107-14:20:00.842(8)? (STDERR) at fileEvaluate (packages/modules-runtime.js:181:9)
W20170107-14:20:00.842(8)? (STDERR) at require (packages/modules-runtime.js:106:16)
W20170107-14:20:00.843(8)? (STDERR) at meteorInstall.lib.lib.js (lib/lib.js:21:29)
W20170107-14:20:00.843(8)? (STDERR) at fileEvaluate (packages/modules-runtime.js:181:9)
W20170107-14:20:00.843(8)? (STDERR) at require (packages/modules-runtime.js:106:16)
W20170107-14:20:00.844(8)? (STDERR) at app.js:6:1
W20170107-14:20:00.844(8)? (STDERR) at /Users/monsterstep/dev/repos/dashboard-app-maker/.meteor/local/build/programs/server/boot.js:295:34
W20170107-14:20:00.844(8)? (STDERR) at Array.forEach (native)
React = require('react')
if (process.env.NODE_ENV !== 'production') {
const {whyDidYouUpdate} = require('why-did-you-update')
whyDidYouUpdate(React)
}
I'm not sure but could this cause issues for react@15 users?
https://github.com/garbles/why-did-you-update/blob/master/package.json#L25
For example:
https://www.npmjs.com/package/debug#browser-support
I tried with a slow React Native app receiving websocket data. After a few seconds and nearly 5,000 warnings it froze my laptop.
I'd like to pull request with a fix. Some ideas:
It could be opt-in, via option.
whyDidYouUpdate(React, {
cutoffLimit: 2000,
})
whyDidYouUpdate(React, {
oncePerComponent: true,
})
// etc
As opposed to just showing that props are unchanged.
When there are a large number of diffs, it could be useful to group them first by component, before grouping by the prop which changed.
A minimal implementation of this is:
diff --git a/src/index.js b/src/index.js
index 8db94a5..5a46514 100644
--- a/src/index.js
+++ b/src/index.js
@@ -27,7 +27,9 @@ function createComponentDidUpdate (opts) {
diffProps(prevProps, this.props, displayName)
.concat(diffState(prevState, this.state, displayName))
+ console.groupCollapsed(displayName)
diffs.forEach(opts.notifier)
+ console.groupEnd()
}
}
But I am guessing a more robust (and possibly configurable?) solution would be better. Let me know if you think this feature is worth adding and I'm happy to put in a PR.
Getting this error after updating to the newly released version.
Anyone?
'lowPriorityWarning.js:40 Warning: Accessing createClass via the main React package is deprecated, and will be removed in React v16.0. Use a plain JavaScript class instead. If you\'re not yet ready to migrate, create-react-class v15.* is available on npm as a temporary, drop-in replacement. For more info see https://fb.me/react-create-class'
Uncaught TypeError: Cannot set property createClass of #<Object> which has only a getter
at whyDidYouUpdate (index.js:41)
at Object../components/stage.js (stage.js:10)
at __webpack_require__ (bootstrap bb0dfdd…:659)
at fn (bootstrap bb0dfdd…:85)
at Object../app.js (app.js:1)
at __webpack_require__ (bootstrap bb0dfdd…:659)
at fn (bootstrap bb0dfdd…:85)
at Object.0 (scaffolds.scss?f3be:26)
at __webpack_require__ (bootstrap bb0dfdd…:659)
at ../node_modules/ansi-html/index.js.module.exports (bootstrap bb0dfdd…:708)
There is a typo in a variable use in the source code:
https://github.com/garbles/why-did-you-update/blob/master/src/index.js#L12
pre
is not defined. I imagine this would affect core functionality?
Tried running this on React Native ver 0.45.1 (uses React 16.0.0-alpha.12). I receive the following error: Cannot set property createClass of # which has only a getter.
The error occures in ~/why-did-you-update/lib/index.js:41:4.
Any ideas what might be causing this?
Where do you place the code within the app? Any suggestions if one is using Webpack?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.