-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Class constructor doesn't have reference to this.props #8583
Comments
Hey @aray12! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
Would you be able to look in the bundled JS file from Webpack to see what Babel's compiled output for this class looks like? |
I'm having similar issues with Typescript + Babel 7. Class properties are getting set to |
Hey sorry for the late response. The following is the component that is causing the problem, but when I moved the offending line into // @flow
import React, { Component } from 'react';
import ReactModal from 'react-modal';
import cx from 'classnames';
import { IndexLink } from 'react-router';
import { compose, withProps } from 'recompose';
ReactModal.setAppElement('#app');
import styles from './Modal.local.scss';
import SkillxLogo from '../assets/sx-logo.react.svg';
import BackButton from 'components/Navigation/Container/Shell/BackButton/BackButton';
import Icon from 'components/Visual/Icon/Icon';
import { withBreakpoints, BREAKPOINTS } from 'features/Breakpoints';
import { Scrollbars } from 'features/Scrollbars';
import { DEFAULT_LOADING_ANIMATION_DELAY_MODAL } from 'constants/misc';
const decorate = compose(
withBreakpoints(),
withProps(({ isSmallerThan }) => ({
isMobile: isSmallerThan(BREAKPOINTS.LARGE),
}))
);
type Props = {
isOpen: boolean,
children: any,
onRequestClose?: Function,
size: 'mid' | 'large',
isLoading: boolean,
loadingDelay: number,
isClosable: boolean,
isMobile: boolean,
getRef?: Function,
};
type State = {
bodyOpenClassName: string,
isDelayed: boolean,
};
class Modal extends Component<Props, State> {
props: Props;
state: State;
modalRef: any;
contentRef: any;
timeout: number;
static defaultProps = {
size: 'mid',
loadingDelay: DEFAULT_LOADING_ANIMATION_DELAY_MODAL,
isClosable: true,
};
constructor(props: Props) {
super(props);
this.state = {
bodyOpenClassName: `ReactModal__Body--open--${Math.random()
.toString(36)
.substring(5)}`,
isDelayed: true,
};
if (this.props.getRef) this.props.getRef(this);
}
componentDidMount() {
const { isLoading, loadingDelay } = this.props;
if (isLoading) {
this.timeout = setTimeout(
() => this.setState({ isDelayed: false }),
loadingDelay
);
}
}
componentDidUpdate(prevProps: Props) {
const { isLoading, loadingDelay } = this.props;
if (!prevProps.isLoading && isLoading) {
this.timeout = setTimeout(
() => this.setState({ isDelayed: false }),
loadingDelay
);
}
if (prevProps.isLoading && !isLoading) {
clearTimeout(this.timeout);
this.setState({ isDelayed: true }); // eslint-disable-line react/no-did-update-set-state
}
}
componentWillUnmount() {
clearTimeout(this.timeout);
}
scrollToTop = () => {
if (this.props.isMobile) {
if (this.contentRef) {
this.contentRef.parentNode.scrollTop = 0;
}
} else if (this.modalRef) {
this.modalRef.portal.overlay.scrollTop = 0;
}
};
render() {
const {
children,
onRequestClose,
size,
isLoading,
isClosable,
isMobile,
...rest
} = this.props;
const { isDelayed } = this.state;
return (
<ReactModal
bodyOpenClassName={this.state.bodyOpenClassName}
overlayClassName={{
base: cx(styles.overlay, styles[size]),
afterOpen: styles.afterOpen,
beforeClose: styles.beforeClose,
}}
className={{
base: cx(styles.modalWrap, styles[size], {
[styles.loading]: isLoading && !isDelayed,
}),
afterOpen: styles.afterOpen,
beforeClose: styles.beforeClose,
}}
closeTimeoutMS={500}
contentLabel="Modal"
onRequestClose={onRequestClose}
shouldReturnFocusAfterClose={false}
{...rest}
ref={c => {
if (c) {
this.modalRef = c;
}
}}
>
<div
className={cx(styles.modal, styles[size], {
[styles.loading]: isLoading && !isDelayed,
})}
>
<div className={cx('text-center', styles.header, styles[size])}>
{isClosable && (
<BackButton
onClick={onRequestClose}
className="hide-for-large margined-left-small"
/>
)}
<IndexLink tabIndex="-1" to="/" className={styles.logo}>
<SkillxLogo />
</IndexLink>
{isClosable && (
<button
onClick={onRequestClose}
className={cx(styles.closeBtn, 'show-for-large')}
tabIndex="-1"
>
<Icon
icon={['fal', 'times']}
size="2x"
className="color-medium-gray"
/>
</button>
)}
</div>
{!isMobile && (
<div className={cx(styles.content, 'row')}>{children}</div>
)}
{isMobile && (
<Scrollbars style={{ height: 'calc(100vh - 50.5px)' }}>
<div
ref={ref => {
this.contentRef = ref;
}}
className={cx(styles.content, 'row')}
>
{children}
</div>
</Scrollbars>
)}
</div>
</ReactModal>
);
}
}
export default decorate(Modal); The output is this import _withProps from "recompose/withProps";
import _compose from "recompose/compose";
var _jsxFileName = "/opt/app/src/components/Modal/Modal.js";
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { Component } from 'react';
import ReactModal from 'react-modal';
import cx from 'classnames';
import { IndexLink } from 'react-router';
ReactModal.setAppElement('#app');
import styles from './Modal.local.scss';
import SkillxLogo from '../assets/sx-logo.react.svg';
import BackButton from 'components/Navigation/Container/Shell/BackButton/BackButton';
import Icon from 'components/Visual/Icon/Icon';
import { withBreakpoints, BREAKPOINTS } from 'features/Breakpoints';
import { Scrollbars } from 'features/Scrollbars';
import { DEFAULT_LOADING_ANIMATION_DELAY_MODAL } from 'constants/misc';
var decorate = _compose(withBreakpoints(), _withProps(function (_ref) {
var isSmallerThan = _ref.isSmallerThan;
return {
isMobile: isSmallerThan(BREAKPOINTS.LARGE)
};
}));
/*:: type Props = {
isOpen: boolean,
children: any,
onRequestClose?: Function,
size: 'mid' | 'large',
isLoading: boolean,
loadingDelay: number,
isClosable: boolean,
isMobile: boolean,
getRef?: Function,
};*/
/*:: type State = {
bodyOpenClassName: string,
isDelayed: boolean,
};*/
var Modal =
/*#__PURE__*/
function (_Component) {
_inherits(Modal, _Component);
function Modal(props
/*: Props*/
) {
var _this;
_classCallCheck(this, Modal);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Modal).call(this, props));
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "props", void 0);
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", void 0);
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "modalRef", void 0);
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "contentRef", void 0);
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "timeout", void 0);
_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "scrollToTop", function () {
if (_this.props.isMobile) {
if (_this.contentRef) {
_this.contentRef.parentNode.scrollTop = 0;
}
} else if (_this.modalRef) {
_this.modalRef.portal.overlay.scrollTop = 0;
}
});
_this.state = {
bodyOpenClassName: "ReactModal__Body--open--".concat(Math.random().toString(36).substring(5)),
isDelayed: true
};
// NEXT LINE -- Uncaught TypeError: Cannot read property 'getRef' of undefined
if (_this.props.getRef) _this.props.getRef(_assertThisInitialized(_assertThisInitialized(_this)));
return _this;
}
_createClass(Modal, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this2 = this;
var _this$props = this.props,
isLoading = _this$props.isLoading,
loadingDelay = _this$props.loadingDelay;
if (isLoading) {
this.timeout = setTimeout(function () {
return _this2.setState({
isDelayed: false
});
}, loadingDelay);
}
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps
/*: Props*/
) {
var _this3 = this;
var _this$props2 = this.props,
isLoading = _this$props2.isLoading,
loadingDelay = _this$props2.loadingDelay;
if (!prevProps.isLoading && isLoading) {
this.timeout = setTimeout(function () {
return _this3.setState({
isDelayed: false
});
}, loadingDelay);
}
if (prevProps.isLoading && !isLoading) {
clearTimeout(this.timeout);
this.setState({
isDelayed: true
});
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
clearTimeout(this.timeout);
}
}, {
key: "render",
value: function render() {
var _this4 = this;
var _this$props3 = this.props,
children = _this$props3.children,
onRequestClose = _this$props3.onRequestClose,
size = _this$props3.size,
isLoading = _this$props3.isLoading,
isClosable = _this$props3.isClosable,
isMobile = _this$props3.isMobile,
rest = _objectWithoutProperties(_this$props3, ["children", "onRequestClose", "size", "isLoading", "isClosable", "isMobile"]);
var isDelayed = this.state.isDelayed;
return React.createElement(ReactModal, _extends({
bodyOpenClassName: this.state.bodyOpenClassName,
overlayClassName: {
base: cx(styles.overlay, styles[size]),
afterOpen: styles.afterOpen,
beforeClose: styles.beforeClose
},
className: {
base: cx(styles.modalWrap, styles[size], _defineProperty({}, styles.loading, isLoading && !isDelayed)),
afterOpen: styles.afterOpen,
beforeClose: styles.beforeClose
},
closeTimeoutMS: 500,
contentLabel: "Modal",
onRequestClose: onRequestClose,
shouldReturnFocusAfterClose: false
}, rest, {
ref: function ref(c) {
if (c) {
_this4.modalRef = c;
}
},
__source: {
fileName: _jsxFileName,
lineNumber: 139
}
}), React.createElement("div", {
className: cx(styles.modal, styles[size], _defineProperty({}, styles.loading, isLoading && !isDelayed)),
__source: {
fileName: _jsxFileName,
lineNumber: 165
}
}, React.createElement("div", {
className: cx('text-center', styles.header, styles[size]),
__source: {
fileName: _jsxFileName,
lineNumber: 170
}
}, isClosable && React.createElement(BackButton, {
onClick: onRequestClose,
className: "hide-for-large margined-left-small",
__source: {
fileName: _jsxFileName,
lineNumber: 172
}
}), React.createElement(IndexLink, {
tabIndex: "-1",
to: "/",
className: styles.logo,
__source: {
fileName: _jsxFileName,
lineNumber: 177
}
}, React.createElement(SkillxLogo, {
__source: {
fileName: _jsxFileName,
lineNumber: 178
}
})), isClosable && React.createElement("button", {
onClick: onRequestClose,
className: cx(styles.closeBtn, 'show-for-large'),
tabIndex: "-1",
__source: {
fileName: _jsxFileName,
lineNumber: 181
}
}, React.createElement(Icon, {
icon: ['fal', 'times'],
size: "2x",
className: "color-medium-gray",
__source: {
fileName: _jsxFileName,
lineNumber: 186
}
}))), !isMobile && React.createElement("div", {
className: cx(styles.content, 'row'),
__source: {
fileName: _jsxFileName,
lineNumber: 195
}
}, children), isMobile && React.createElement(Scrollbars, {
style: {
height: 'calc(100vh - 50.5px)'
},
__source: {
fileName: _jsxFileName,
lineNumber: 198
}
}, React.createElement("div", {
ref: function ref(_ref2) {
_this4.contentRef = _ref2;
},
className: cx(styles.content, 'row'),
__source: {
fileName: _jsxFileName,
lineNumber: 199
}
}, children))));
}
}]);
return Modal;
}(Component);
_defineProperty(Modal, "defaultProps", {
size: 'mid',
loadingDelay: DEFAULT_LOADING_ANIMATION_DELAY_MODAL,
isClosable: true
});
export default decorate(Modal);
//////////////////
// WEBPACK FOOTER
// ./src/components/Modal/Modal.js
// module id = Xpbu
// module chunks = 14 |
@aray12 Cool, then this is the same issue as #8417 My recommendation would be to delete these lines
since I don't think they are needed when you have then already passed via
Basically you shouldn't declare a class property if you're not actually the one creating and assigning it. |
Ahh interesting. I have been continuing to do that because that is what our older version of Thanks for the help and all of the amazing work on this project! |
v7 Regression
Potential Commit/PR that introduced the regression
If you have time to investigate, what PR/date introduced this issue.
This is my first intro to babel 7
Describe the regression
A clear and concise description of what the regression is.
I use babel-upgrade in order to upgrade to babel 7 and everything appears to be working perfectly except one thing. We have a reference to
this.props
in our constructor in a couple of places that was working before, but nowthis.props
seems to be undefined. We do callsuper(props)
prior to referencing them.Input Code
Babel Configuration (.babelrc, package.json, cli command)
Expected behavior/code
A clear and concise description of what you expected to happen (or code).
Environment
The text was updated successfully, but these errors were encountered: