Giter Site home page Giter Site logo

welldone-software / why-did-you-render Goto Github PK

View Code? Open in Web Editor NEW
10.8K 39.0 187.0 8.51 MB

why-did-you-render by Welldone Software monkey patches React to notify you about potentially avoidable re-renders. (Works with React Native as well.)

Home Page: https://www.npmjs.com/package/@welldone-software/why-did-you-render

License: MIT License

JavaScript 97.62% TypeScript 2.35% Shell 0.03%
react component pure performance render update tool react-native purecomponent hooks-tracking

why-did-you-render's People

Contributors

alex-page avatar andersdjohnson avatar barakyosi avatar bduff9 avatar busybox11 avatar dependabot[bot] avatar ereddrex avatar genhain avatar hrazmsft avatar hypnosphi avatar iamakulov avatar igorrmotta avatar jared-hexagon avatar jfrumar-infinitusai avatar jnachtigall avatar joelbrenstrum avatar joeyparis avatar jussikinnula avatar kostasx avatar leroydev avatar lpmi-13 avatar mbman avatar mostafah avatar nirvdrum avatar noramens avatar oliverjash avatar sergeylaptev avatar theehsansarshar avatar vzaidman avatar xepozz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

why-did-you-render's Issues

No logs

I've installed this package and I'm using it on my react native project like this:

if (process.env.NODE_ENV !== 'production') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React);
}

But I get no log/error at all.

Do I need to do anything after install package?

"@welldone-software/why-did-you-render": "^3.0.0-beta.5",
"react": "16.8.3"
"react-native": "0.59.2"

react-redux 7 uses useMemo, all Connected components complaining

Great job on the new release!
I just updated react-redux to 7.0.1 and WDYR is complaining about every single one. How should we handle this?

Connect(Header)
whyDidYouRender.min.js:8 {Connect(Header): ƒ} "Re-rendered because of hook changes:"
whyDidYouRender.min.js:8 hook useMemo 
whyDidYouRender.min.js:8 different React elements with the same displayName. (more info at http://bit.ly/wdyr3)
whyDidYouRender.min.js:8 {"prev ": {…}} "!==" {"next ": {…}}

"different functions with the same name", but I'm using useCallback.

I've tried posting this on StackOverflow with no response was hoping to get some more detail here. I recreated a very simple project to replicate what's going on in a bigger project of mine. https://github.com/DaleSalcedo/PropFunctionProblem. In my App.js I'm passing down this function:

const modifyPlayer = React.useCallback((playerId, propertyName, value) => {
    const playerCopy = {...playerDict[playerId]};
    playerCopy[propertyName] = value;
    const playerDictCopy = {
      ...playerDict,
      [playerId]: playerCopy
    };
    setPlayerDict(playerDictCopy);  // useState function
  }
  ,[playerDict]);

I pass that down 2 components as props and use it here:

export const Player = ({player, modifyPlayer}) => {
  const handleOnChange = React.useCallback((event) => {
    modifyPlayer(player.id, event.target.name, event.target.value);
  }, [player, modifyPlayer]);

  return (
    <div>
      <input type={"text"} name={"firstName"} value={player.firstName} onChange={handleOnChange}/>
      <input type={"text"} name={"lastName"} value={player.lastName} onChange={handleOnChange}/>
    </div>
  );
};

I'm not sure why it's giving me that message "different functions with the same name" for "modifyPlayer" function when I used "useCallback".

Is this a bug or can someone explain what's going on?

Functions in useContext API

Hello,

I have a Context API component to show/hide a modal. I'm using something very similar to the Toast example from here: Ponyfoo Toast

WDYR gives me this error:
Captura de Tela 2019-06-03 às 10 39 51

How can I avoid this re-render? Or it is normal react behavior?

All functions are created using useCallback, I've already tried adding memo to both the <Header />(the component that I tested WDYR) and the <Context.Provider />

Any ideas?

Thanks in advance

Does this lib has debugger?

React ver: 16.8.6
why-did-you-render ver: 3.2.1

No any output in console. How I can check if the library is working?

Setup code:
import whyDidYouRender from '@welldone-software/why-did-you-render'
whyDidYouRender(React)

Снимок экрана 2019-07-03 в 16 57 24

Component code:
Снимок экрана 2019-07-03 в 16 58 17

False Positive

Getting warning:
"Re-rendered because the state object itself changed but it's values are all equal." "This usually means this component called setState when no changes in it's state actually occurred." "more info at http://bit.ly/wdyr02"
prev state: Object {} !== Object {} :next state

I added a console log of the props, and it can be seen that its only rendering once per prop change.

The component:

class MyComp extends PureComponent {
    static whyDidYouRender = true;

    render() {
        console.log('rerendered', this.props.downloadProgress);
        return (
            <View/>
        );
    }
}

const mapStateToProps = state => ({
    downloadProgress: getDownloadProgress(state),
});

export default connect(mapStateToProps)(MyComp);

Every time the prop changes causing a rerender I get the warning above that the warning is unnecessary, which is false.

It may also be worth noting that this component is opened/hosted via react-navigation.

Eslint plugin

Just an idea - create an eslint plugin that helps users prevent common mistakes that cause unnecessary rerenders like <Component style={{ background: 'black' />.

Recompose "Pure" wipes logs

Hi

I used this lib and its great. So I started to fixing my rerending problems. I added Recompose's Pure() HOC to check how it goes. My rerenders still occur, but the logs are missing.

More info about 'different functions with the same name'

Hello,

Love this plugin but the information in the readme and in the blog post about 'different functions with the same name' is really sparse.

Can you explain what this means a bit more in the docs and how to fix it?

I'm getting these warnings a lot and since the functions are the same (not different functions) it's hard to figure out what to do about it.

A little more information about this particular warning would be super helpful.

Thanks!

create-react-app React performance with SVG as ReactComponent and eslint with React.memo missing display name

I'm using this component in a create-react-app app:

import { ReactComponent as ProfileIcon } from "./icons/profile.svg";

...
render(){
  <ProfileIcon {...props}/>
}

Using also why-did-you-render (https://github.com/welldone-software/why-did-you-render) I got this warning:

SvgProfileIcon
whyDidYouRender.min.js:1191 {SvgProfileIcon: ƒ} "Re-rendered because the props object itself changed but it's values are all equal." "This could of been avoided by making the component pure, or by preventing it's father from re-rendering." "more info at http://bit.ly/wdyr02"
whyDidYouRender.min.js:1191 prev props: {svgRef: null, className: "icon", height: "24", width: "24"} !== {svgRef: null, className: "icon", height: "24", width: "24"} :next props

So I made a custom PureComponent like this:

import React from "react";

export default WrappedComponent =>
  React.memo(props => <WrappedComponent {...props} />, () => true);

FIRST QUESTION: Is this performances-correct?

I'm using it like this:

import { ReactComponent as ProfileIcon } from "./icons/profile.svg";

import PureComponent from "./PureComponent";

const PureProfileIcon = PureComponent(ProfileIcon);

...
render(){
  <PureProfileIcon {...props}/>
}

SECOND QUESTION: Can I avoid this component at all using React.memo (or something else) differently?

Now eslint is complaining about:

Component definition is missing display name eslint(react/display-name)

THIRD QUESTION: How can I fix this?

Export default notifier?

I would like to keep the defaultNotifier but extend some of the values, such as displayName with some info from the props, to make it easier to identify the troublesome component.

react-i18next re-render

It seems that "react-i18next" triggers a re-render of the component.
What step do you think is the best course of action?

Screenshot 2019-06-06 at 01 10 24

3RD party debugging(Reactotron via realm.js edition)

I recently made the pull request for #64 and it was not out of philanthropy and more necessity.
I am on React Native using realm.js and anyone who has tried using realm on React Native knows that it has some issues.

After browsing solutions in the issues of Realm, you will come across people mentioning Reactotron. It works wonderfully with a few tweaks.

The issue is that the Reactotron is, it does not seem to have an equivalent function of console.group() and console.groupEnd() which the default notifier of this library uses.

Now of course this library allows you you to pass in a notifier options to handle it yourself, but it has quite a fair amount of data returned to you which can be overwhelming initially for you to figure out what is going on. I have created a gist which i hope has similar behaviour to the default console. Some feedback/corrections would be appreciated as i think this is a fantastic tool but anyone using a similar stack to me might not find it easy to use.

Another thing i have noticed is that React.memo() seems to suppress why did you render logs but was supposed to be fixed in v3.3.4 as the closing comment in #50 says

Kind Of false positive when using `React.StrictMode`

When running whyDidYouRender on a tree rendered inside StrictMode, e.g.

<React.StrictMode>
  <MyComponent />
</React.StrictMode>

I get this after any legitimate (e.g. props changed) update:

Re-rendered although props and state objects are the same. This usually means there was a call to this.forceUpdate() inside the component.

This happens because StrictMode renders each components twice to catch bugs related to side effects in render. I wonder if those second renders could be filtered out somehow

TypeError: Cannot read property '_prevProps' of undefined

I'm trying to start wide then narrow it down - I have a large set of components involved in a complex form and going component by component at this point to turn on would be painful. I see Consumer and Provider types are failing with the cannot be invoked without 'new' error, no problem anyway, I am not interested in them. But I get to a point where I have no info on what to ignore to continue.

if (process.env.NODE_ENV === 'development') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render')
  whyDidYouRender(React, {
    exclude: [/Consumer|Provider|AutoSignout/],
    include: [/^.*/],
  })
}
whyDidYouRender.min.js:8 Uncaught (in promise) TypeError: Cannot read property '_prevProps' of undefined
    at value (whyDidYouRender.min.js:8)
    at f.o.render (whyDidYouRender.min.js:8)
    at createElements.js:38

Any thoughts on determining the offending displayName here?

Clarity about React Native

Does this library work with React Native? If so, are there any additional steps? In any case, updating README would be useful.

PS: Thanks for the great work!

Hooks are not supported

functional components with hooks work as expected regarding their props.

but we dont have a way right now to track state changes that are caused by the "useState" hook for example even if they trigger a render with similar state.

Uncaught RangeError: Maximum call stack size exceeded

On this commit, as soon as I use even only try to start my app with /registration, it gets into an infinite loop. Edit: the other, technically working, routes /login, /factories and /mines also crash.

The above error occurred in the <Registration> component:
    in Registration (created by Context.Consumer)
    in Route (at Routes.tsx:28)
    in Switch (at Routes.tsx:19)
    in main (at Routes.tsx:18)
    in Routes (at RHelper.tsx:17)
    in RHelper (at src/index.tsx:30)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Context.Consumer)
    in ConnectedRouterWithContext (created by Context.Consumer)
    in Connect(ConnectedRouterWithContext) (at src/index.tsx:29)
    in PersistGate (at src/index.tsx:28)
    in Provider (at src/index.tsx:27)

It's stuck on useState(false)
Bildschirmfoto 2019-04-05 um 20 06 17

one level up:
Bildschirmfoto 2019-04-05 um 20 07 24

Did I miss anything concerning documentation or is it the mix of tools I use?

Doesn't show anything in console

I don't know what I'm doing wrong, but nothing is shown in the console.

This is how I set it up:
I execute whyDidYouRender in index.tsx like this:

if (process.env.NODE_ENV !== 'production') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React);
}

ReactDOM.render(<App />, document.getElementById('root'));

And I added the static property whyDidYouRender to App.tsx
App.whyDidYouRender = true;

I don't know if I missing something

Include original error in log output

Issue

When an error is caught and a message is logged to the console to report the error and has details about the component etc. the actual error being thrown is not logged:

Screen Shot 2019-06-17 at 11 28 01 am

This is not very helpful. You have to add a breakpoint yourself.

Solution

Include the original error as a property in the object that is logged.

An error is thrown if `renderToStaticMarkup` is used somewhere

To reproduce, add anywhere on top-level of your app:

class MyComponent extends React.Component {
  render() {
    return null
  }
}
const string = React.renderToStaticMarkup(<MyComponent/>);

Error in console:

Uncaught TypeError: Cannot read property 'mode' of undefined
    at whyDidYouRender.min.js:8
    at f.value (whyDidYouRender.min.js:8)
    at processChild (react-dom-server.browser.development.js:2958)
    at resolve (react-dom-server.browser.development.js:2811)
    at ReactDOMServerRenderer.render (react-dom-server.browser.development.js:3201)
    at ReactDOMServerRenderer.read (react-dom-server.browser.development.js:3160)
    at renderToStaticMarkup (react-dom-server.browser.development.js:3660)

Looks like renderToStaticMarkup doesn't set _reactInternalFiber property on component instances

Here's my usecase for renderToStaticMarkup: in my app, there are only some parts rendered by React, while other are rendered by server templates. To use third-party (BitBucket) svg icon in non-React parts of the app, I convert a React component from Atlaskit library to static svg string with renderToStaticMarkup, and then inject it in a CSS rule.

class constructors must be invoked with |new|

Trying to implement base functionality on our existing React app.

Getting

class constructors must be invoked with |new|

for any component I add the static property to.

It looks like this is a common issue across this library and the predecessors, but I was under the impression this library had it solved, so I must be missing something.

I've attached the library via NPM as well as manually adding the src to see if I could narrow it down. Best I can tell the error is thrown here (line 505):
_this = _possibleConstructorReturn(this, _getPrototypeOf(WDYRPatchedClassComponent).call(this, props, context));

Excluding markup, my component looks like this:
`class Home extends React.Component {

constructor(props) {
super(props);
}
static whyDidYouRender = true;
render(){
...
}
export default Home;
`

wrong message when useMemo re-renders

In the following case:

const A = () => {
   const obj = useMemo(() => ({
     // something big
  }), [a, b, c, d, e]);

 return <Child  obj={obj} />;
}

when the hook useMemo re-creates obj even if it's deps deep equals, the message says A was re-rendered because if it, where in reality useMemo re-generated obj without a reason, but A is not re-rendered because of this.

There was no `forceUpdate`, but getting that as error message

I'm seeing lots of:
Re-rendered although props and state objects are the same. This usually means there was a call to this.forceUpdate() inside the component.

However, nowhere in those components is there a forceUpdate(). So what could that mean?

Usage with multiple instances of a component

Hi,

it seems the library in designed around 'big' components that exists only once in the tree. Are there any plans to support multiple instances of functional components?

Best regards
Marco

Scala.Js compatibility

Hi, this might be outside the scope of your intended use-cases, but I'm trying to transcompile javascript using ScalaJs and was wondering if you might be able to advise on an error I'm getting when using why-did-you-render in my React 16.8.4 application:

react-dom.development.js?4646:20312 Uncaught TypeError: t.include.some is not a function
    at eval (_freeGlobal.js?7bdd:2)
    at ro (_freeGlobal.js?7bdd:2)
    at ko (_freeGlobal.js?7bdd:2)
    at Object.eval [as useState] (_freeGlobal.js?7bdd:2)
    at Object.useState (react.development.js?9c48:1462)
    at client-fastopt.js:27081
    at $c_sjsr_AnonFunction1.apply__O__O (client-fastopt.js:25930)

Here is relevant info from errorInfo object that gets printed when tries to work on my main functional component:

displayName: "main "
options: include: ƒ (arg1) {
arguments: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.remoteFunction (<anonymous>:2:14)]
caller: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.remoteFunction (<anonymous>:2:14)]
length:1
name:""
}

I am calling why-did-you-render with include: /.*/ to avoid polluting my code as described in the docs.

Higher-order components from react redux router "withRouter" seem to be ignored

[email protected]
[email protected]
[email protected]
[email protected]

I am attempting to use why-did-you-render to debug some of my route components. The main route container is calling the Search component like so:

...
<Switch>
  <Route exact path="/">
     <Redirect to="/search" />
  </Route>
  <Route path="/search" component={Search} />
  <Route path="/project" component={Project} />
</Switch>
...

and the Search component is being exported using the withRouter HOC from react-router-dom like so:

...
export default withRouter(Search)

As far as I can tell, it is not currently possible to debug any component that has been wrapped with the withRouter HOC.

[NEXT.JS] TypeError: Object.defineProperty called on non-object

I'm facing issues using NextJs. I'd tried different ways to do it but always the same results.
Even in build mode and dev mode, the issue is the same just change the file names because of the hashes.

I import React globally, so I don't have to put: class NameClass extends React.Component/

I also tried to import in different scenarios mentioned in the doc and also using require and import, but didn't work.

I don't have any modifications in babel plugins and etc, but NextJS have their own.
This is preset:
https://github.com/zeit/next.js/blob/canary/packages/next/build/babel/preset.ts

I think that looking into this you can assume if any plugin is causing this issue.

In this screenshot is the issue when I start a server with builded version:
Screen Shot 2019-04-10 at 10 10 41

browserlist, TypeError: Class constructor "Component" cannot be invoked without 'new'

TypeError: Class constructor "Component" cannot be invoked without 'new'

Using the create-react-app 3, why-did-you-render: v3.0.6 and this import:

const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.min.js')

why-did-you-render: v3.0.6

My browserlist:

  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }

Unable to get it work on Expo

Hi,
today im trying to work in expo and unable to get it work, something missing?

here the code:

import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';

if (__DEV__) {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React);
}

console.log('Example log')

export default class App extends React.Component {
  static whyDidYouRender = true
  constructor(props) {
    super(props);
    this.state = {
      visible: false
    };
  }
  render() {
    const { visible } = this.state;
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={() => this.setState({ visible: !visible })}>
          <Text>{visible ? 'Hide' : 'Show'}</Text>
        </TouchableOpacity>
        { visible === true && <Text style={{ marginTop: 16 }}>Hidden content</Text> }
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  }
});

and here the link to snack:

https://snack.expo.io/@outatime/why-did-you-render

Thanks !!!

What to do with react-router?

Many times I have problem with <Link ... /> and <Route ... /> maybe with something like:

<Route
  path={`${match.url}/:player_id`}
  children={props => (
    <PlayerDetail {...props} teamId={match.params.team_id} />
  )}
/>
Route
whyDidYouRender.min.js:1185 {Route: ƒ} "Re-rendered because of props changes:"
whyDidYouRender.min.js:1190 props.children
whyDidYouRender.min.js:1190 different functions with the same name.
whyDidYouRender.min.js:1190 {prev children: ƒ} "!==" {next children: ƒ}

Can we make a Wiki page (or you have already planned a future article) just for react-router?

React Native 0.60.5 fails to launch and memory goes through the roof

Seems like this library works when running React Native but only when the debugger is attached - which I think implies it has to do with the JavaScript engine (when attaching the debugger it runs V8). It goes for both iOS and Android - on the device and simulator.

It launches the app - succeeds in running decent amounts of JavaScript code i can tell from the logs - but fails to render. Memory consumption goes through the roof during this process as well (after about a minute my app was consuming almost 10gb of memory).

It doesn't render the library completely unusable with RN but it bugs me to have to manually comment the whole library out when I want to run it without an attached debugger - which is usually the case since it has some heavy performance implications.

can't work with React.memo

I've created a memo Component, but it's no output in my console.

when I remove memo function in my component, it works.

Is it because the why-did-you-render does not support React.memo?

React.useRef is returning empty string

Uncaught TypeError: Cannot create property 'current' on string ''
    at trackHookChanges (whyDidYouRender.js:149)
    at Object.useMemo (whyDidYouRender.js:260)
    at useMemo (react.development.js:1525)
    at TakeNotes (index.tsx:18)

Screenshot 2019-06-24 at 12 55 55

I'm getting this fatal error while running .whyDidYouRender on one of my React components.

Bug when component is wrapped in memo and forwardRef

Issue

When a React functional component is wrapped in both React.memo and React.forwardRef with why-did-you-render enabled you get this error:

ncaught TypeError: WrappedFunctionalComponent is not a function
    at WDYRWrappedByMemoFunctionalComponent (whyDidYouRender.js:740)
    at renderWithHooks (react-dom.development.js:13449)
    at mountIndeterminateComponent (react-dom.development.js:15605)
    at beginWork (react-dom.development.js:16238)
    at performUnitOfWork (react-dom.development.js:20279)
    at workLoop (react-dom.development.js:20320)
    at renderRoot (react-dom.development.js:20400)
    at performWorkOnRoot (react-dom.development.js:21357)
    at performWork (react-dom.development.js:21267)
    at performSyncWork (react-dom.development.js:21241)
    at requestWork (react-dom.development.js:21096)
    at scheduleWork (react-dom.development.js:20909)
    at scheduleRootUpdate (react-dom.development.js:21604)
    at updateContainerAtExpirationTime (react-dom.development.js:21630)
    at updateContainer (react-dom.development.js:21698)
    at ReactRoot.push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:22011)
    at react-dom.development.js:22163
    at unbatchedUpdates (react-dom.development.js:21486)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:22159)
    at Object.render (react-dom.development.js:22234)
    at Module../src/index.js (index.js:7)
    at __webpack_require__ (bootstrap:781)
    at fn (bootstrap:149)
    at Object.0 (serviceWorker.js:135)
    at __webpack_require__ (bootstrap:781)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1

or when minified:

Uncaught TypeError: o is not a function

Repro

https://github.com/jared-hexagon/whydidyourender-memo-forwardref

https://codesandbox.io/s/github/jared-hexagon/whydidyourender-memo-forwardref

Details

Does this work with expo RN apps?

Hi.
I've followed the setup as per the docs and tried some other variations, all to no avail.

Any reason why this shouldn't work?

Here's my App.tsx file:

import React from 'react'
import { StyleSheet, Text, View, Button } from 'react-native'

if (process.env.NODE_ENV !== 'production') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.min.js')
  whyDidYouRender(React)
}

const { useState } = React

const TestComp = () => {
  const [visible, setVisible] = useState(false)
  return (
    <View>
      {visible && (
        <View>
          <Text>Is Visible</Text>
        </View>
      )}
      <Button
        title="Press Me!"
        onPress={() => {
          setVisible(true)
        }}
      />
    </View>
  )
}

TestComp.whyDidYouRender = true

const App = () => {
  return (
    <View style={styles.container}>
      <TestComp />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  }
})

export default App


An error occures when the package is imported via dynamic import

Hello!

I faced a problem playing around with React Hooks and this package.
When dynamic import of the package is used like that:

import("@welldone-software/why-did-you-render").then(whyDidYouRender => {
  whyDidYouRender(React, {
    onlyLogs: true,
    titleColor: "green",
    diffNameColor: "darkturquoise"
  });
});

the following error occurs:

proxyConsole.js:72 Warning: React has detected a change in the order of Hooks called by Example. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks

   Previous render            Next render
   ------------------------------------------------------
1. useState                   useState
2. undefined                  useRef
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    in Example (at src/index.js:19)
    in App (at src/index.js:23)
console.<computed> @ proxyConsole.js:72
i.<computed> @ index.js:27
r @ backend.js:6529
warningWithoutStack @ react-dom.development.js:506
warning @ react-dom.development.js:2628
warnOnHookMismatchInDev @ react-dom.development.js:12860
updateHookTypesDev @ react-dom.development.js:12826
useRef @ react-dom.development.js:13834
useRef @ react.development.js:1472
ko @ whyDidYouRender.min.js:8
eval @ whyDidYouRender.min.js:8
useState @ react.development.js:1462
Example @ index.js? [sm]:4
renderWithHooks @ react-dom.development.js:12938
updateFunctionComponent @ react-dom.development.js:14627
beginWork @ react-dom.development.js:15637
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
renderRoot @ react-dom.development.js:19435
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
interactiveUpdates$1 @ react-dom.development.js:20495
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
react-dom.development.js:55 Uncaught Invariant Violation: Rendered more hooks than during the previous render.
    at invariant (https://jdq0k.csb.app/node_modules/react-dom/cjs/react-dom.development.js:55:15)
    at updateWorkInProgressHook (https://jdq0k.csb.app/node_modules/react-dom/cjs/react-dom.development.js:13092:35)
    at updateRef (https://jdq0k.csb.app/node_modules/react-dom/cjs/react-dom.development.js:13334:14)

I created an example to show the problem.

If you'll try to change something in the code, it can start working at some point, but if you reload the page, the issue will occure again (I think it is related to CodesandBox work).

Also, I have a project on my local machine with the same package version. When using dynamic import I can see the following error:
image
because it is an object with a key "default":
image
and I have to use destructuring to get it:

import("@welldone-software/why-did-you-render").then(({ default: whyDidYouRender }) => {

Don't know why, but in the sandbox the function "To" is taken by default and destructuring is not needed.

I'd like to know, first, how to use dynamic import with the package and with React Hooks (it would be better do not to make the bundle bigger using regular import), second, why the parameter that is taken from the package can be the function itself or the object with "default" key, why are they different. Is that a problem with React support of this feature?

Thanks in advance.

[Question] ability to add to all components?

First, thanks for such an amazing tool with hooks support. Incredibly helpful.

We have over 100 components in our project, and it will take a long time to manually add Component.whyDidYouRender = true; in every single file.

Is there a way to attach to everything? I see the [include] option, but we are currently not using DisplayName - so we would still have to touch every file.

Thanks for the help.

Breaks child.type comparisons

This will always return an empty array when activated:

const MenuItem = React.forwardRef((props, ref) => { return <div>Example</div> })
MenuItem.whyDidYouRender = true

let focusableChildrenTypes = [MenuItem]

let isFocusableChildType = (child): child is React.ReactElement =>
  focusableChildrenTypes.includes(child.type)
let getFocusableMenuChildren = (children) => {
  let focusable: any[] = []
  React.Children.forEach(children, (child) => {
    console.log('Checking focusable', child.type === MenuItem)
    if (isFocusableChildType(child)) focusable.push(child)
  })
  return focusable
}

Is there a way to get this module to work with child.type comparisons? Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.