why-did-you-render icon indicating copy to clipboard operation
why-did-you-render copied to clipboard

How to use in CRA(5.0.0) React17.0.1

Open aaamrh opened this issue 2 years ago • 13 comments

I tried a lot of ways,but it dosen't show any information in console. I don't know what's wrong.

import { times } from "lodash";
import React from "react";
import ReactDOM from "react-dom";
import whyDidYouRender from "@welldone-software/why-did-you-render";

if (process.env.NODE_ENV === 'development') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React, {
    trackAllPureComponents: true,
  });
}

class BigListPureComponent extends React.PureComponent {
  static whyDidYouRender = true;
  render() {
    console.log(
      "BigListPureComponent Re-Render! - We don't want to get here too often."
    );
    return (
      <div style={this.props.style}>
        <h2>BigListPureComponent</h2>
        <div>
          {times(3000).map((n) => (
            <div key={n}>Element #{n}</div>
          ))}
        </div>
      </div>
    );
  }
}

const bigListStyle = { width: "100%" }; // eslint-disable-line no-unused-vars

// Notice, that unlike the huge list, we don't track Main's re-renders because we don't care about it's re-renders.
class Main extends React.Component {
  state = { count: 0 };
  render() {
    return (
      <div
        style={{
          height: "100%",
          width: "100%",
          display: "flex",
          flexDirection: "column"
        }}
      >
        <h1>Big List (Main Demo)</h1>
        <p>
          {
            'Open the console and notice how the heavy list re-renders on every click on "Increase!" even though it\'s props are the same.'
          }
        </p>
        <div>
          <button
            onClick={() => {
              this.setState({ count: this.state.count + 1 });
            }}
          >
            Increase!
          </button>
        </div>
        <div>
          <span>Count: {this.state.count}</span>
        </div>
        <BigListPureComponent style={{ width: "100%" }} />
        <BigListPureComponent />
      </div>
    );
  }
}

ReactDOM.render(<Main />, document.getElementById("root"));

aaamrh avatar Jan 26 '22 03:01 aaamrh

The discussion on CRA 4 is here: #154. I'll try to look at CRA 5 this week.

vzaidman avatar Jan 26 '22 10:01 vzaidman

The discussion on CRA 4 is here: #154. I'll try to look at CRA 5 this week.

I really appreciate it 😀

aaamrh avatar Jan 28 '22 02:01 aaamrh

+1

mohammadgarmroodi avatar Jan 29 '22 09:01 mohammadgarmroodi

+1

austinschrader avatar Feb 16 '22 02:02 austinschrader

+1

GastonVidart avatar Apr 07 '22 13:04 GastonVidart

This works for [email protected], [email protected], and [email protected]. Probably, If you use another way of modifying CRA then the logic of changing 'babel-preset-react-app' is identical.

//config-overrides.js
const isDev = process.env.NODE_ENV === 'development'

module.exports = CRA.override(
  isDev && enableWhyDidYouRender,
)

function enableWhyDidYouRender(config) {
  const options = CRA.getBabelLoader(config).options,
    babelPresetReact = options.presets.find(preset => preset[0].includes('babel-preset-react-app'))

  if (babelPresetReact) {
    const settingsOfBabelPresetReact = babelPresetReact[1]
    settingsOfBabelPresetReact.development = true
    settingsOfBabelPresetReact.importSource = '@welldone-software/why-did-you-render'
  }

  return config
}
//index.tsx
import React from 'react'
import { render } from 'react-dom'
import { enableWhyDidYouRender } from './configs/why-did-you-render'

enableWhyDidYouRender(React)

function AppRoot() { return <div /> }

render(<AppRoot />, document.getElementById('root'))
//why-did-you-render.ts
import React from 'react'
import whyDidYouRender from '@welldone-software/why-did-you-render'

export function enableWhyDidYouRender(react: typeof React) {
  if (process.env.NODE_ENV !== 'development') return
  whyDidYouRender(react, {
    include: [],
    exclude: [],
    trackAllPureComponents: true,
    trackHooks: true,
    logOwnerReasons: true,
    logOnDifferentValues: false,
    collapseGroups: true,
  })
}

LyulyaevMaxim avatar May 19 '22 09:05 LyulyaevMaxim

@LyulyaevMaxim, Hi! i'm trying to reproduce your example, but my attempt was unsuccessful. Could you please show me where i made a mistake?

Here is codesandbox link

chervyakovru avatar Jun 08 '22 21:06 chervyakovru

The welldone-software/[email protected] really does not support react 17 and 18. You can check it with official sandbox Updating react version to 17.0.0 or 18.0.0 in file package.json breaks wdyr functionality

karpo518 avatar Jun 22 '22 21:06 karpo518

The welldone-software/[email protected] really does not support react 17 and 18. You can check it with official sandbox Updating react version to 17.0.0 or 18.0.0 in file package.json breaks wdyr functionality

This has to do with how the sandbox is implemented rather than the library's support. Please see the tests in the package that prove that it does works with the versions specified in the readme.

vzaidman avatar Jun 22 '22 22:06 vzaidman

I came here because I couldn't run wdyr on my project. I copied the contents of the sandbox files into my project and it didn't work in my environment. I am using react 18.1.0 Maybe I'm doing something wrong. However, I can't run the sandboxed example locally.

karpo518 avatar Jun 22 '22 22:06 karpo518

I came here because I couldn't run wdyr on my project. I copied the contents of the sandbox files into my project and it didn't work in my environment. I am using react 18.1.0 Maybe I'm doing something wrong. However, I can't run the sandboxed example locally.

please follow the installation instructions in the readme closely rather than how it works in the sandbox.

vzaidman avatar Jun 23 '22 08:06 vzaidman

Using React 18(.2) I managed to make it work the following way (the way described here didn't work for me, got errors when starting with craco start) :

  1. Install the latest version of the package from npm as a dev dependency:

    npm i -D @craco/craco
    
  2. Create a CRACO configuration file in your project's root directory and configure:

      my-app
      ├── node_modules
    + ├── craco.config.js
      └── package.json
    

(basicaly, craco install from their doc)

  1. Add a calls to the craco CLI in the scripts section of your package.json to use it (or not) :

    "scripts": {
      "start": "react-scripts start"
    + "craco-start": "craco start"
      "build": "react-scripts build"
      "test": "react-scripts test"
    }
    
  2. add the following to my-app/craco.config.js :

module.exports = {
  babel: {
    loaderOptions: (babelLoaderOptions) => {
        // Look up if we find the proper settings
        const origBabelPresetReactAppIndex = babelLoaderOptions.presets.findIndex(preset => {
            return preset[0].includes('babel-preset-react-app\\index.js')
        });

        if (origBabelPresetReactAppIndex === -1) {
            return babelLoaderOptions;
        }

        let origBabelPresetReactApp = babelLoaderOptions.presets[origBabelPresetReactAppIndex][1];

        // if this is not set to automatic, no change
        if(origBabelPresetReactApp.runtime !== "automatic") return babelLoaderOptions;

        // Add the required options
        origBabelPresetReactApp = {
            ...origBabelPresetReactApp,
            development: process.env.NODE_ENV === 'development',
            importSource: '@welldone-software/why-did-you-render',
        }

        babelLoaderOptions.presets[origBabelPresetReactAppIndex][1] = origBabelPresetReactApp;


     return babelLoaderOptions;
    }
  },
};
  1. Add the my-app/src/wdyr.js like the README suggests :
import React from 'react';

if (process.env.NODE_ENV === 'development') {
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React, {
    trackAllPureComponents: true,
    // any other option you require
  });
}
  1. Add the call to wdyr.js to your point of entry (my-app/index.(t|j)sx) :
import './wdyr'; // just that line, don't touch anything else from that file
import './index.css';
import React from 'react';
// ...

root.render(/* your app component */);

reportWebVitals();

  1. Add tracking to the required components.

  2. Start developping with

npm run craco-start

This is close to what @LyulyaevMaxim did in his comment. Now that I did it on my own I understand what he was suggesting, but according to their documentation, react-app-rewired only supports CRA 2.0 and customize-cra also.

I hope it will help fellows lazy developpers who don't want to read documentation and just copy/paste something that works (at least for me).

sebastien-f avatar Nov 30 '22 14:11 sebastien-f

I had to add include: [/./] to @LyulyaevMaxim 's answer to make it work. Can't make it work with craco. P.S @LyulyaevMaxim Btw, does trackExtraHooks work for you?

scientist1642 avatar Aug 20 '23 19:08 scientist1642