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

Does this look right? #37

Closed
silentpickle opened this issue Feb 28, 2017 · 12 comments
Closed

Does this look right? #37

silentpickle opened this issue Feb 28, 2017 · 12 comments

Comments

@silentpickle
Copy link

I tried with the codepen yesterday, and the only thing I could get to recreate the stack trace here was having no elements... which I viewed as somewhat a hint.

However, even in the basic sense... I still get this when I go to use it.

Uncaught Error: React.Children.only expected to receive a single React element child.
at invariant (invariant.js:44)
at Object.onlyChild [as only] (onlyChild.js:33)
at Measure.render (Measure.js:162)
at eval (ReactCompositeComponent.js:796)
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:362)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)

Does this render look in the realm of sense?

render(){
return ({dimensions => <div className={'banner-component'}>});
}

@silentpickle
Copy link
Author

render(){ return (<Measure>{dimensions => <div className={'banner-component'}></div>}</Measure>); }

@silentpickle
Copy link
Author

...or

render(){ return (<Measure><div></div></Measure>); }

Again, I can't make it happen in the codepen, but short of uploading the entirety of the app I'm working on, I don't think I can do an example.

@souporserious
Copy link
Owner

I'm sorry, I can't help unless I know more information about what you are trying to do. Without a reduced test case, all I can tell from the error that you posted is that it looks like you are not passing a single React element to the Measure component. Can you create a repo with a reduced test case showing the error?

@silentpickle
Copy link
Author

silentpickle commented Feb 28, 2017

So, this worked.
render(){ return (<div><Measure onMeasure={(dimensions) => { console.log("measure callback"); console.log(dimensions); }}><div></div></Measure></div>); }
This produces the aforementioned stack trace:

render(){ return (<Measure onMeasure={(dimensions) => { console.log("measure callback"); console.log(dimensions); }}><div></div></Measure>); }

Weeeeeeeeird. That really is my render. Just Measure and a div. This does exactly what I need it to at this point other than causing me to scratch my head on this.

I'm going to follow up on this post in a moment about whether this has to do with some of the decorating we do outside of this.... one being a higher order component exposed and one not might be a hint.

Thank you for the help!

@silentpickle
Copy link
Author

Long story short, this can be closed-out, there's a bunch of super.render() in the framework that I'm sure is using this in a manner other than directed on the label.

@anthonygreco
Copy link

@silentpickle curious if you ever got react-measure to work on CodePen? I get the same error when trying to use the UMD version and updated my React references (JS settings where you can add libs) to use the full dev copy instead of the minified versions and the error got a little bit clearer:

react-dom.js:17896 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `App`.
    at invariant (react-dom.js:17896)
    at instantiateReactComponent (react-dom.js:16037)
    at instantiateChild (react-dom.js:4267)
    at react-dom.js:4294
    at traverseAllChildrenImpl (react-dom.js:16549)
    at traverseAllChildren (react-dom.js:16644)
    at Object.instantiateChildren (react-dom.js:4293)
    at ReactDOMComponent._reconcilerInstantiateChildren (react-dom.js:10378)
    at ReactDOMComponent.mountChildren (react-dom.js:10417)
    at ReactDOMComponent._createInitialChildren (react-dom.js:6164)

I'm uncertain of how to resolve, but maybe @souporserious can give us some direction. I see that when I log Measure in my local project where everything works fine I get a function returned:

Measure function _class() {
  var _ref;
  var _temp, _this, _ret;
  _classCallCheck(this, _class);
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }
  return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
    contentRect: {
      entry: {},
      client: {},
      offset: {},
      scroll: {},
      bounds: {},
      margin: {}
    }
  }, _this.measure = function (entries) {
    var contentRect = (0, _getContentRect2.default)(_this._node, types || (0, _getTypes2.default)(_this.props));
    if (entries) {
      contentRect.entry = entries[0].contentRect;
    }
    _this.setState({ contentRect: contentRect });
    if (typeof _this.props.onResize === 'function') {
      _this.props.onResize(contentRect);
    }
  }, _this._handleRef = function (node) {
    if (_this._resizeObserver) {
      if (node) {
        _this._resizeObserver.observe(node);
      } else {
        _this._resizeObserver.disconnect(_this._node);
      }
    }
    _this._node = node;
    if (typeof _this.props.innerRef === 'function') {
      _this.props.innerRef(node);
    }
  }, _temp), _possibleConstructorReturn(_this, _ret);
}

but the UMD returns an Object in CodePen:

Measure Object {
  __esModule: true,
  default: function _class() {
    var _ref;
    var _temp, _this, _ret;
    _classCallCheck(this, _class);
    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
      contentRect: {
        entry: {},
        client: {},
        offset: {},
        scroll: {},
        bounds: {},
        margin: {}
      }
    }, _this.measure = function (entries) {
      var contentRect = (0, _getContentRect2.default)(_this._node, types || (0, _getTypes2.default)(_this.props));
      if (entries) {
        contentRect.entry = entries[0].contentRect;
      }
      _this.setState({ contentRect: contentRect });
      if (typeof _this.props.onResize === 'function') {
        _this.props.onResize(contentRect);
      }
    }, _this._handleRef = function (node) {
      if (_this._resizeObserver) {
        if (node) {
          _this._resizeObserver.observe(node);
        } else {
          _this._resizeObserver.disconnect(_this._node);
        }
      }
      _this._node = node;
      if (typeof _this.props.innerRef === 'function') {
        _this.props.innerRef(node);
      }
    }, _temp), _possibleConstructorReturn(_this, _ret);
  },
  withContentRect: function withContentRect(types) {
    return function (WrappedComponent) {
      var _class, _temp2;
      return _temp2 = _class = function (_Component) {
        _inherits(_class, _Component);
        function _class() {
          var _ref;
          var _temp, _this, _ret;
          _classCallCheck(this, _class);
          for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }
          return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
            contentRect: {
              entry: {},
              client: {},
              offset: {},
              scroll: {},
              bounds: {},
              margin: {}
            }
          }, _this.measure = function (entries) {
            var contentRect = (0, _getContentRect2.default)(_this._node, types || (0, _getTypes2.default)(_this.props));
            if (entries) {
              contentRect.entry = entries[0].contentRect;
            }
            _this.setState({ contentRect: contentRect });
            if (typeof _this.props.onResize === 'function') {
              _this.props.onResize(contentRect);
            }
          }, _this._handleRef = function (node) {
            if (_this._resizeObserver) {
              if (node) {
                _this._resizeObserver.observe(node);
              } else {
                _this._resizeObserver.disconnect(_this._node);
              }
            }
            _this._node = node;
            if (typeof _this.props.innerRef === 'function') {
              _this.props.innerRef(node);
            }
          }, _temp), _possibleConstructorReturn(_this, _ret);
        }
        _createClass(_class, [{
          key: 'componentWillMount',
          value: function componentWillMount() {
            this._resizeObserver = new _resizeObserverPolyfill2.default(this.measure);
          }
        }, {
          key: 'render',
          value: function render() {
            var _props = this.props,
                innerRef = _props.innerRef,
                onResize = _props.onResize,
                props = _objectWithoutProperties(_props, ['innerRef', 'onResize']);
            return (0, _react.createElement)(WrappedComponent, _extends({}, props, {
              measureRef: this._handleRef,
              measure: this.measure,
              contentRect: this.state.contentRect
            }));
          }
        }]);
        return _class;
      }(_react.Component), _class.propTypes = {
        client: _propTypes2.default.bool,
        offset: _propTypes2.default.bool,
        scroll: _propTypes2.default.bool,
        bounds: _propTypes2.default.bool,
        margin: _propTypes2.default.bool,
        innerRef: _propTypes2.default.func,
        onResize: _propTypes2.default.func,
        children: _propTypes2.default.func
      }, _temp2;
    };
  }
}

@silentpickle
Copy link
Author

The codepen stuff I never got working.

For better/worse, we had a 'super.render()' that was being called, and that wasn't helping me out much. I didn't dive too deep into that because ultimately we went with a breakpoint-based solution, more-or-less. Nothing against this library, it's just the design constraints were to fit a given 2-3 resolutions, anyway, so, no point in outfitting nukes when grenades will do.

The thing that saved me (and it was up further in here anyway) was returning this, but with a blank 'div' wrapper.

@souporserious
Copy link
Owner

@anthonygreco sorry about that! The UMD build returns an object with Measure attached to default. I've forked your Codepen to show you how you can use it. I need to update the docs, sorry about that.

@anthonygreco
Copy link

anthonygreco commented Jun 8, 2017

@souporserious Apologies. I should've mentioned that I tried that, to no avail. While the pen loads since a valid variable is being used, it doesn't actually work. The handle resize is never called, which is why no data is displayed. Is there more work that needs to be done to get Measure working in CodePen?

FWIW, I updated my pen to point to a copy of the UMD build on my own server and it looks like it fails on line 222:

this._resizeObserver = new _resizeObserverPolyfill2.default(this.measure);

logging that variable returns an object with an undefined default property:

Object {
  default: undefined
}

@amanmahajan7
Copy link

amanmahajan7 commented Sep 29, 2017

I am ruining into the same issue with TypeScript.

import Measure, { ChildrenOpts, ContentRect } from 'react-measure';

const TestComponent: React.SFC<Props> = () => {
   <Measure bounds onResize={onTooltipResize}>
      {
        ({ measureRef }: ChildrenOpts) =>
          <div>TEST</div>
      }
   </Measure>
}

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components)

console.log(Measure); is undefined

Any suggestions would be highly appreciated. Thanks

@silentpickle
Copy link
Author

silentpickle commented Sep 29, 2017

Just for amusement, give this a shot.... if I'm not missing something (I'm not the best TypeScript guy out there)

const TestComponent: React.SFC<Props> = () => {
   <div><Measure bounds onResize={onTooltipResize}>
      {
        ({ measureRef }: ChildrenOpts) =>
          <div>TEST</div>
      }
   </Measure></div>
}

@amanmahajan7
Copy link

This seems to be related to add-module-exports babel plugin. I have created a new issue
#82

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants