Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use in CRA(5.0.0) React17.0.1 #231

Open
aaamrh opened this issue Jan 26, 2022 · 13 comments
Open

How to use in CRA(5.0.0) React17.0.1 #231

aaamrh opened this issue Jan 26, 2022 · 13 comments
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@aaamrh
Copy link

aaamrh commented Jan 26, 2022

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"));
@vzaidman vzaidman added good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested labels Jan 26, 2022
@vzaidman
Copy link
Collaborator

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

@aaamrh
Copy link
Author

aaamrh commented Jan 28, 2022

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

I really appreciate it 😀

@mohammadgarmroodi
Copy link

+1

1 similar comment
@austinschrader
Copy link

+1

@GastonVidart
Copy link

+1

@LyulyaevMaxim
Copy link

This works for react-scripts@5.0.0, react-app-rewired@2.2.1, and customize-cra@1.0.0.
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,
  })
}

@chervyakovru
Copy link

chervyakovru commented Jun 8, 2022

@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

@karpo518
Copy link

karpo518 commented Jun 22, 2022

The welldone-software/why-did-you-render@7.0.1 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

@vzaidman
Copy link
Collaborator

The welldone-software/why-did-you-render@7.0.1 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.

@karpo518
Copy link

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.

@vzaidman
Copy link
Collaborator

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.

@sebastien-f
Copy link

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).

@scientist1642
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

10 participants