welldone-software / why-did-you-render

why-did-you-render by Welldone Software monkey patches React to notify you about potentially avoidable re-renders. (Works with React Native as well.)
https://www.npmjs.com/package/@welldone-software/why-did-you-render
MIT License
11.21k stars 201 forks source link

"React has detected a change in the order of Hooks" error when using whyDidYouRender #86

Closed timothyarmes closed 4 years ago

timothyarmes commented 4 years ago

I'm getting this following error when whyDidYouRender is installed:

Warning: React has detected a change in the order of Hooks called by Loadable. 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. useState                   useRef
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    in Loadable (created by App)
    in App
modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:20409 Uncaught Error: Rendered more hooks than during the previous render.
    at updateWorkInProgressHook (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:20409)
    at updateReducer (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:20469)
    at Object.useReducer (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:21344)
    at useReducer (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:2667)
    at UseReducer (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:33267)
    at Loadable (npdev_react-loadable.js?hash=039e4bdcc4dbeb7e8c023730b148822578a28e50:134)
    at renderWithHooks (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:20258)
    at updateFunctionComponent (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:22345)
    at beginWork$1 (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:24174)
    at HTMLUnknownElement.callCallback (modules.js?hash=cf91e80bb6a92ce6bf5b22f1696910335cea0791:4334)

Loadable is a fork of react-loadable for Meteor: https://github.com/CaptainN/npdev-react-loadable I've been through the Loadable source, but as far as I can tell there are no issues with hook order change. Futhermore, the bug only occurs when whyDidYouRender is installed.

Also worthy of note is that version 3.4.2 of whyDidYouRender works fine. It fails as of 3.5.0. I am calling whyDidYouRender as soon as possible.

I've created a very simple meteor project to replicate the issue:

http://www.timothyarmes.com/private/whyRenderBug.zip

Run with

npm install
meteor
vzaidman commented 4 years ago

you need to make sure you call whyDidYouRender(React); as soon as possible, before you do anything else.

timothyarmes commented 4 years ago

Sorry, I pressed save before entering all the information. I've updated my report and included a small project to demonstrate the issue.

vzaidman commented 4 years ago

The bug happens because react-loadable does some unusual React work as soon as it is imported and we got to run whyDidYouRender even earlier.

I got to fix it by importing ./wdyr like this in Main.jsx:

import './wdyr';

import React from 'react';
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import Loadable from '/imports/ui/Loadable'

Meteor.startup(() => {
  render(<Loadable />, document.getElementById('react-target'));
});

Where wdyr.jsx looks like this:

import React from 'react';
import { Meteor } from 'meteor/meteor';

if (Meteor.isDevelopment && Meteor.isClient) {
  const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.js');
  whyDidYouRender(React);
}
timothyarmes commented 4 years ago

Thank you!