Styled-jsx: Dynamic interpolations that contain "this" fail under some circumstances

Created on 1 Sep 2018  路  1Comment  路  Source: vercel/styled-jsx

The interpolation below works in next v5 but since v6 (which uses babel 7) it throws a TypeError: Cannot read property 'props' of undefined.

export default class Index extends React.Component {
  static getInitialProps() {
    return { color: 'aquamarine' };
  }

  render() {
    return (
      <div>
        {[1,2].map(idx => <div key={idx}>{this.props.color}</div>)}
        <style jsx>{`
          div {
            background: ${this.props.color};
          }
        `}</style>
      </div>
    );
  }
}

Sample apps

Details

Below is the babel output of the class for both applications. Note how in next 5 both this.props.color expressions, that is, the style interpolation and the div children, are compiled to _this2.props.color. However, in next 7, the style interpolation is compiled to this.props.color while the div children is compiled to _this.props.color.

Compiled class in next 5 app

_createClass(Index, [{
  key: 'render',
  value: function render() {
    var _this2 = this;

    return __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement(
      'div',
      {
        className: __WEBPACK_IMPORTED_MODULE_0_styled_jsx_style___default.a.dynamic([['1028791522', [_this2.props.color]]]),
        __source: {
          fileName: _jsxFileName,
          lineNumber: 8
        }
      },
      [1, 2].map(function (idx) {
        return __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement(
          'div',
          { key: idx, className: __WEBPACK_IMPORTED_MODULE_0_styled_jsx_style___default.a.dynamic([['1028791522', [_this2.props.color]]]),
            __source: {
              fileName: _jsxFileName,
              lineNumber: 9
            }
          },
          _this2.props.color
        );
      }),
      __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_0_styled_jsx_style___default.a, {
        styleId: '1028791522',
        css: 'div.__jsx-style-dynamic-selector{background:' + _this2.props.color + ';}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2VzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNvQixBQUdxRCx3Q0FDMUMiLCJmaWxlIjoicGFnZXMvaW5kZXguanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL2dhYnJpZWwvQ29kZS9uZXh0LTUtc3R5bGVkLWpzeC10aGlzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW5kZXggZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBzdGF0aWMgZ2V0SW5pdGlhbFByb3BzKCkge1xuICAgIHJldHVybiB7IGNvbG9yOiAnYXF1YW1hcmluZScgfTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAge1sxLDJdLm1hcChpZHggPT4gPGRpdiBrZXk9e2lkeH0+e3RoaXMucHJvcHMuY29sb3J9PC9kaXY+KX1cbiAgICAgICAgPHN0eWxlIGpzeD57YFxuICAgICAgICAgIGRpdiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAke3RoaXMucHJvcHMuY29sb3J9O1xuICAgICAgICAgIH1cbiAgICAgICAgYH08L3N0eWxlPlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuIl19 */\n/*@ sourceURL=pages/index.js */',
        dynamic: [_this2.props.color]
      })
    );
  }
}, {
  key: '__reactstandin__regenerateByEval',
  value: function __reactstandin__regenerateByEval(key, code) {
    this[key] = eval(code);
  }
}], [{
  key: 'getInitialProps',
  value: function getInitialProps() {
    return { color: 'aquamarine' };
  }
}]);

Compiled class in next 7 app

_createClass(Index, [{
  key: "render",
  value: function render() {
    var _this = this;

    return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", {
      __source: {
        fileName: _jsxFileName,
        lineNumber: 8
      },
      className: styled_jsx_style__WEBPACK_IMPORTED_MODULE_0___default.a.dynamic([["1028791522", [this.props.color]]])
    }, [1, 2].map(function (idx) {
      return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", {
        key: idx,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 9
        },
        className: styled_jsx_style__WEBPACK_IMPORTED_MODULE_0___default.a.dynamic([["1028791522", [this.props.color]]])
      }, _this.props.color);
    }), react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(styled_jsx_style__WEBPACK_IMPORTED_MODULE_0___default.a, {
      styleId: "1028791522",
      css: "div.__jsx-style-dynamic-selector{background:".concat(this.props.color, ";}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2VzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNvQixBQUdxRCx3Q0FDMUMiLCJmaWxlIjoicGFnZXMvaW5kZXguanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL2dhYnJpZWwvQ29kZS9uZXh0LTctc3R5bGVkLWpzeC10aGlzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW5kZXggZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBzdGF0aWMgZ2V0SW5pdGlhbFByb3BzKCkge1xuICAgIHJldHVybiB7IGNvbG9yOiAnYXF1YW1hcmluZScgfTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAge1sxLDJdLm1hcChpZHggPT4gPGRpdiBrZXk9e2lkeH0+e3RoaXMucHJvcHMuY29sb3J9PC9kaXY+KX1cbiAgICAgICAgPHN0eWxlIGpzeD57YFxuICAgICAgICAgIGRpdiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAke3RoaXMucHJvcHMuY29sb3J9O1xuICAgICAgICAgIH1cbiAgICAgICAgYH08L3N0eWxlPlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuIl19 */\n/*@ sourceURL=pages/index.js */"),
      dynamic: [this.props.color]
    }));
  }
}], [{
  key: "getInitialProps",
  value: function getInitialProps() {
    return {
      color: 'aquamarine'
    };
  }
}])
bug

Most helpful comment

thanks Gabriel, that's indeed a bug and has to do with AST nodes reusing. We probably don't clone some node. We had a similar issue before https://github.com/zeit/styled-jsx/pull/470

>All comments

thanks Gabriel, that's indeed a bug and has to do with AST nodes reusing. We probably don't clone some node. We had a similar issue before https://github.com/zeit/styled-jsx/pull/470

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rauchg picture rauchg  路  18Comments

rauchg picture rauchg  路  25Comments

Tomekmularczyk picture Tomekmularczyk  路  22Comments

thysultan picture thysultan  路  24Comments

tomsoderlund picture tomsoderlund  路  18Comments