Topic: My app breaks when I update to 4.12 or later

mpcooke4 pro asked 5 years ago


I have been puzzling over this issues all day, so thought I'd ask in case it's related to a change that you know about.

Expected behavior I am using react-scripts to start and build my react app and usually it all runs ok with a mdbreact pro github dependancy in my package.json script

Actual behavior

On npm start, the app starts up but in the browser I get an error related to the react object being undefined in an mdbreact script.

TypeError: Cannot read property 'type' of undefined (anonymous function) node_modules/mdbreact/dist/mdbreact.esm.js:6552 6549 | var contentClasses = classNames(!popover && "tooltip-inner"); 6550 | return React.createElement(Manager, null, React.createElement(Reference, null, function (_ref2) { 6551 | var ref = _ref2.ref;

6552 | return !domElement ? React.createElement(Wrapper.type, _extends({}, Wrapper.props, { | ^ 6553 | onMouseEnter: function onMouseEnter() { 6554 | return !clickable && setVisible(true); 6555 | },

Resources (screenshots, code snippets etc.)

I have "react": "^16.8.2" in my dependancies and I am using the github URL in my package.json file to load mdbreact and I can switch between a working (for me) version of mdbreact and the latest version that doesn't work by switching from:

git.mdbootstrap.com/mdb/react/re-pro.git#fcdbb72d <- Working git.mdbootstrap.com/mdb/react/re-pro.git#9c308706 <- Broken git.mdbootstrap.com/mdb/react/re-pro.git <- Broken

I don't really know how the magic of webpack works and what might have changed that react is included in one version okay but doesn't get included in the later version.


mpcooke4 pro commented 5 years ago

Just to follow up, I have a looked a bit closer at the changes around the time it stopped working for me and in the mdbreact package.json file, react and reactdom were both moved to devDependencies. What I don't understand is why that is causing me problems and no one else!


mpcooke4 pro commented 5 years ago

Should react be a peer dependancy rather than a dev dependancy to ensure the react library is available?


Jakub Mandra staff commented 5 years ago

Hi,

react should be in your dependencies, so as react-dom. Please try to use React 16.8.6. Error msg tells that the problem is caused by Popover/Tootlip component which is built using hooks.

If it won't help, please contact me for further assistance.

Best,

Jakub


mpcooke4 pro commented 5 years ago

I have react and react-dom in my package.json dependancies: "react": "^16.8.6", "react-dom": "^16.8.6",

I also tried deleting nodemodules and running npm install again. react is downloaded into my nodemodules. I don't understand why it still doesn't work after adding it and re-installing everything, perhaps it's something to do with webpack although I am just using react-scripts.

What I do know for sure is I can make it work if I pin the mdbreact version to before you moved the dependancies into dev.

Here is the error, after ensuring package.json has react 16.8.6, deleting nodemodules and a fresh npm install × ←→1 of 8 errors on the page TypeError: Cannot read property 'type' of undefined (anonymous function) node_modules/mdbreact/dist/mdbreact.esm.js:6749 6746 | var contentClasses = classNames(!popover && "tooltip-inner"); 6747 | return React.createElement(Manager, null, React.createElement(Reference, null, function (_ref2) { 6748 | var ref = _ref2.ref;

6749 | return !domElement ? React.createElement(Wrapper.type, _extends({}, Wrapper.props, { | ^ 6750 | onMouseEnter: function onMouseEnter() { 6751 | return !clickable && setVisible(true); 6752 | }, View compiled InnerReference.render node_modules/react-popper/lib/esm/Reference.js:36 33 | 34 | _proto.render = function render() { 35 | warning(Boolean(this.props.setReferenceNode), 'Reference should not be used outside of a Manager component.'); 36 | return unwrapArray(this.props.children)({ | ^ 37 | ref: this.refHandler 38 | }); 39 | };


mpcooke4 pro commented 5 years ago

The full error trace shows that this error happens due to a setState call which I make after loading some data in the componentDidMount() method. I thought it was suppose to be okay to do this, but it seems to fail after MDBreact version fcdbb72d with this strange type error. I'll look into it further tomorrow. My react app renders okay when I remove this setState line, albeit without any loaded data of course...

full stack:

× ←→1 of 8 errors on the page TypeError: Cannot read property 'type' of undefined (anonymous function) node_modules/mdbreact/dist/mdbreact.esm.js:6749 6746 | var contentClasses = classNames(!popover && "tooltip-inner"); 6747 | return React.createElement(Manager, null, React.createElement(Reference, null, function (_ref2) { 6748 | var ref = _ref2.ref;

6749 | return !domElement ? React.createElement(Wrapper.type, _extends({}, Wrapper.props, { | ^ 6750 | onMouseEnter: function onMouseEnter() { 6751 | return !clickable && setVisible(true); 6752 | }, View compiled InnerReference.render node_modules/react-popper/lib/esm/Reference.js:36 33 | 34 | _proto.render = function render() { 35 | warning(Boolean(this.props.setReferenceNode), 'Reference should not be used outside of a Manager component.'); 36 | return unwrapArray(this.props.children)({ | ^ 37 | ref: this.refHandler 38 | }); 39 | }; View compiled finishClassComponent node_modules/react-dom/cjs/react-dom.development.js:15320 15317 | } else { 15318 | { 15319 | setCurrentPhase('render'); 15320 | nextChildren = instance.render(); | ^ 15321 | 15322 | if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 15323 | instance.render(); View compiled updateClassComponent node_modules/react-dom/cjs/react-dom.development.js:15275 15272 | shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime); 15273 | } 15274 | 15275 | var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime); | ^ 15276 | { 15277 | var inst = workInProgress.stateNode; 15278 | View compiled beginWork node_modules/react-dom/cjs/react-dom.development.js:16265 16262 | 16263 | var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps); 16264 | 16265 | return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime); | ^ 16266 | } 16267 | 16268 | case HostRoot: View compiled performUnitOfWork node_modules/react-dom/cjs/react-dom.development.js:20285 20282 | startProfilerTimer(workInProgress); 20283 | } 20284 | 20285 | next = beginWork(current$$1, workInProgress, nextRenderExpirationTime); | ^ 20286 | workInProgress.memoizedProps = workInProgress.pendingProps; 20287 | 20288 | if (workInProgress.mode & ProfileMode) { View compiled workLoop node_modules/react-dom/cjs/react-dom.development.js:20326 20323 | if (!isYieldy) { 20324 | // Flush work without yielding 20325 | while (nextUnitOfWork !== null) { 20326 | nextUnitOfWork = performUnitOfWork(nextUnitOfWork); | ^ 20327 | } 20328 | } else { 20329 | // Flush asynchronous work until there's a higher priority event View compiled HTMLUnknownElement.callCallback node_modules/react-dom/cjs/react-dom.development.js:147 144 | window.event = windowEvent; 145 | } 146 | 147 | func.apply(context, funcArgs); | ^ 148 | didError = false; 149 | } // Create a global error event handler. We use this to capture the value 150 | // that was thrown. It's possible that this error handler will fire more View compiled invokeGuardedCallbackDev node_modules/react-dom/cjs/react-dom.development.js:196 193 | // errors, it will trigger our global error handler. 194 | 195 | evt.initEvent(evtType, false, false); 196 | fakeNode.dispatchEvent(evt); | ^ 197 | 198 | if (windowEventDescriptor) { 199 | Object.defineProperty(window, 'event', windowEventDescriptor); View compiled invokeGuardedCallback node_modules/react-dom/cjs/react-dom.development.js:250 247 | function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { 248 | hasError = false; 249 | caughtError = null; 250 | invokeGuardedCallbackImpl$1.apply(reporter, arguments); | ^ 251 | } 252 | /** 253 | * Same as invokeGuardedCallback, but instead of returning an error, it stores View compiled replayUnitOfWork node_modules/react-dom/cjs/react-dom.development.js:19509 19506 | 19507 | isReplayingFailedUnitOfWork = true; 19508 | originalReplayError = thrownValue; 19509 | invokeGuardedCallback(null, workLoop, null, isYieldy); | ^ 19510 | isReplayingFailedUnitOfWork = false; 19511 | originalReplayError = null; 19512 | View compiled renderRoot node_modules/react-dom/cjs/react-dom.development.js:20439 20436 | if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 20437 | if (mayReplay) { 20438 | var failedUnitOfWork = nextUnitOfWork; 20439 | replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy); | ^ 20440 | } 20441 | } // TODO: we already know this isn't true in some cases. 20442 | // At least this shows a nicer error message until we figure out the cause. View compiled performWorkOnRoot node_modules/react-dom/cjs/react-dom.development.js:21363 21360 | cancelTimeout(timeoutHandle); 21361 | } 21362 | 21363 | renderRoot(root, isYieldy); | ^ 21364 | finishedWork = root.finishedWork; 21365 | 21366 | if (finishedWork !== null) { View compiled performWork node_modules/react-dom/cjs/react-dom.development.js:21273 21270 | } 21271 | } else { 21272 | while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) { 21273 | performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false); | ^ 21274 | findHighestPriorityRoot(); 21275 | } 21276 | } // We're done flushing work. Either we ran out of time in this callback, View compiled performSyncWork node_modules/react-dom/cjs/react-dom.development.js:21247 21244 | } 21245 | 21246 | function performSyncWork() { 21247 | performWork(Sync, false); | ^ 21248 | } 21249 | 21250 | function performWork(minExpirationTime, isYieldy) { View compiled requestWork node_modules/react-dom/cjs/react-dom.development.js:21102 21099 | 21100 | 21101 | if (expirationTime === Sync) { 21102 | performSyncWork(); | ^ 21103 | } else { 21104 | scheduleCallbackWithExpirationTime(root, expirationTime); 21105 | } View compiled scheduleWork node_modules/react-dom/cjs/react-dom.development.js:20915 20912 | !isWorking || isCommitting$1 || // ...unless this is a different root than the one we're rendering. 20913 | nextRoot !== root) { 20914 | var rootExpirationTime = root.expirationTime; 20915 | requestWork(root, rootExpirationTime); | ^ 20916 | } 20917 | 20918 | if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { View compiled enqueueSetState node_modules/react-dom/cjs/react-dom.development.js:11596 11593 | 11594 | flushPassiveEffects(); 11595 | enqueueUpdate(fiber, update); 11596 | scheduleWork(fiber, expirationTime); | ^ 11597 | }, 11598 | enqueueReplaceState: function enqueueReplaceState(inst, payload, callback) { 11599 | var fiber = get(inst); View compiled HomePage.push../node_modules/react/cjs/react.development.js.Component.setState node_modules/react/cjs/react.development.js:336 333 | 334 | Component.prototype.setState = function (partialState, callback) { 335 | !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : void 0; 336 | this.updater.enqueueSetState(this, partialState, callback, 'setState'); | ^ 337 | }; 338 | /** 339 | * Forces an update. This should only be invoked when it is known with View compiled (anonymous function) src/pages/HomePage.js:114 111 | console.log('RulesEngine processed collection size:'+items.length); 112 | const category = this.itemsHelper.findById(rawData,categoryId); 113 | const features = this.itemsHelper.getFeatures(category); 114 | return this.setState({rawData, loaded: true, items, category, userNeeds, features}); | ^ 115 | } 116 | ); 117 | } View compiled This screen is visible only in development. It will not appear if the app crashes in production. Open your browser’s developer console to further inspect this error.


Jakub Mandra staff commented 5 years ago

Can you share your project with us so we could see what is going on there?

You can invite me (@Rotarepmi) on private GitHub repo.

Best,

Jakub


mpcooke4 pro commented 5 years ago

Thanks the project using mdbreact is in cowfoo/new-react-web-client


mpcooke4 pro commented 5 years ago

You probaby read the stack trace better than me, but it isn't React that was undefined, it is wrapper. I still don't understand why upgrading mdbreact would cause that error though.


mpcooke4 pro commented 5 years ago

Let me know if you have any problems reproducing it. I left the breakage in head and granted you access...


Jakub Mandra staff commented 5 years ago

Hi there,

Sorry it took so long, I had problems with installation, caused by "synchronize" package (took some time to find out).

I've checked your project and found what is going on - you're using Popovers/Tooltips old syntax. They were completely rebuilt in 4.13.0 version and their syntax had to be changed.

Check new docs: https://mdbootstrap.com/docs/react/advanced/popovers/

Hope this will help.

Best,

Jakub


mpcooke4 pro commented 5 years ago

Many thanks for identifying the problem!

Does the new syntax support wrapping a popup around an arbitrary element? I can see it can wrap a button okay but it doesn't seem to work on a div - does the wrapped element need to have certain properties?


Jakub Mandra staff commented 5 years ago

Try below code, you just need to add domElement property to you Popover/Tooltip, so it will go on with native elements:

import React from "react";
import { MDBPopover, MDBPopoverBody, MDBPopoverHeader } from "mdbreact";

const PopoverPage = () => {
  return (
        <MDBPopover
          placement="top"
          popover
          clickable
          id="popper1"
          domElement
        >
          <div>popover on top</div>
          <div>
            <MDBPopoverHeader>popover on top</MDBPopoverHeader>
            <MDBPopoverBody>
              Sed posuere consectetur est at lobortis. Aenean eu leo quam.
              Pellentesque ornare sem lacinia quam venenatis vestibulum.
            </MDBPopoverBody>
          </div>
        </MDBPopover>
  );
}

export default PopoverPage;


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Opened

Specification of the issue

  • ForumUser: Pro
  • Premium support: No
  • Technology: MDB React
  • MDB Version: 4.12.0
  • Device: Mac
  • Browser: Chrome
  • OS: osX
  • Provided sample code: No
  • Provided link: No