[vercel/next.js]类型错误:无法读取未定义的属性“组件”

2024-05-15 810 views
4

我正在使用cloudinary-react 库,当我将 Image 组件添加到项目中时,遇到以下错误消息:

在 DOM 中

TypeError: Cannot read property 'Component' of undefined
    at _callee3$ (http://localhost:3000/_next/-/main.js:3977:50)
    at tryCatch (http://localhost:3000/_next/-/commons.js:36939:40)
    at Generator.invoke [as _invoke] (http://localhost:3000/_next/-/commons.js:37230:22)
    at Generator.prototype.(anonymous function) [as next] (http://localhost:3000/_next/-/commons.js:36991:21)
    at step (http://localhost:3000/_next/-/commons.js:3724:30)
    at http://localhost:3000/_next/-/commons.js:3742:14
    at F (http://localhost:3000/_next/-/commons.js:2033:28)
    at http://localhost:3000/_next/-/commons.js:3721:12
    at doRender (http://localhost:3000/_next/-/main.js:3999:18)
    at Object._callee$ (http://localhost:3000/_next/-/main.js:3891:20)

在开发工具中

Warning: React attempted to reuse markup in a container but the checksum was invalid. 
This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. 
React injected new markup to compensate which works but you have lost many of the benefits of server rendering. 
Instead, figure out why the markup being generated is different on the client or server:
 (client) tid="1"><div class="error" data-jsx="676
 (server) tid="1"><div class="wrapper" data-jsx="2

Image 组件采用cloudName& publicId。是publicId一个字符串,表示 Cloudinary API 服务器上附加到用户的cloudName.难道这是 CORS 问题导致出现此错误?我不太确定这在说什么。

回答

4

@rockchalkwushock 你的组件代码是什么样的?因为它基本上看起来就像你在使用extends React.Component而不在某处导入“react”

2

@sakulstra

我从来没有想过组件的含义React.Component,但不幸的是我认为事实并非如此。我确实检查了库上的导入,cloudinary-react以确保解构是正确的导入方式,并且这是正确的。

我已react在使用基于类的组件的任何地方导入,如下所示:

import React, { Component, PropTypes } from 'react';

以下是与此问题相关的容器和组件。如果您想查看全部代码,可以在这里找到其余的代码:

HomePageContainer.js

import { connect } from 'react-redux';
import HomePage from './HomePage';
import { getFetchHomeImages } from './actions';

export default connect(
  state => ({
    images: state.home
  }),
  { getFetchHomeImages }
)(HomePage);

主页.js

import React, { Component, PropTypes } from 'react';
import { Image } from 'cloudinary-react';

class HomePage extends Component {
  static propTypes = {
    getFetchHomeImages: PropTypes.func.isRequired,
    images: PropTypes.array.isRequired
  }
  async componentDidMount() {
    await this.props.getFetchHomeImages(); // fetches the publicId from the photos.json (array of 4 ids)
  }
  render() {
    const { images } = this.props;
    return (
      <div className="home-component">
        <style jsx>{`
          .home-component {
            display: flex;
            flex-direction: column;
            width: 100%;
          }
          .top,
          .bottom {
            display: flex;
            flex: 1 1 auto;
          }
          .top > * {
            flex: 1 1 auto;
            align-items: center;
            justify-content: space-around;
          }
          .bottom > * {
            flex: 1 1 auto;
            align-items: center;
            justify-content: space-around;
          }
          .item {
            padding: 1em;
            border: 5px solid lightgreen;
            text-align: center;
          }`}</style>
        <div className="top">
          <Image
            cloudName='rockchalkwushock'
            publicId={images[0]}
            width='300'
            crop='scale'
          />
          // There will be another <Image /> here
        </div>
        <div className="bottom">
          <img className='item' src={images[2]} alt="Portrait" /> // Will become <Image />
          <img className='item' src={images[3]} alt="Portrait" /> // Will become <Image />
        </div>
      </div>
    );
  }
}
0

我已经做了相当多的实验,但仍然从 next.js 收到相同的错误消息。我创建了一个一次性存储库来继续调查导致此问题的原因,并将向开发团队提出一个问题以cloudinary-react引用此问题和废弃存储库。即使在我可以使用他们的演示数据创建的最简单的示例中,我仍然收到相同的错误。

扔掉回购协议

我认为仅从错误消息来看该问题是 Next.js 相关问题;但是我不确定该<Image/>组件如何做出贡献,因此我向双方提出问题。废弃存储库的README.md中提供了链接。

1

与 Draft.js 有同样的问题吗?

6

@jlcarvalho

感谢您提到这不仅仅是我正在使用的技术和 Next.js 之间的问题。您是否收到完全相同的错误消息?

2

@rockchalkwushock 是的,完全相同的错误。

TypeError: Cannot read property 'Component' of undefined
    at _callee3$ (http://localhost:3000/_next/-/main.js:21620:50)
    at tryCatch (http://localhost:3000/_next/-/commons.js:19828:40)
    at Generator.invoke [as _invoke] (http://localhost:3000/_next/-/commons.js:20119:22)
    at Generator.prototype.(anonymous function) [as next] (http://localhost:3000/_next/-/commons.js:19880:21)
    at step (http://localhost:3000/_next/-/commons.js:2792:30)
    at http://localhost:3000/_next/-/commons.js:2810:14
    at F (http://localhost:3000/_next/-/commons.js:1794:28)
    at http://localhost:3000/_next/-/commons.js:2789:12
    at doRender (http://localhost:3000/_next/-/main.js:21642:18)
    at Object._callee$ (http://localhost:3000/_next/-/main.js:21534:20)
0

@rauchg

在对我在库中使用的内容进行一些研究后,我很好奇问题cloudinary-react是否源于他们通过构建CloudinaryComponent基于类的组件所做的事情。然后,他们Component在构建库中使用的组件时使用它:

IE。 class Image extends CloudinaryComponent { code here }

我使用打开了一个快速存储库create-react-app,但此错误并不像 Next.js 中那样出现。因此,我粗略地认为问题确实存在于 Next.js 代码及其解释组件的方式中Image

我正在抓住救命稻草,因为此时大部分源代码都通过了我的理解;但由于错误所指,Cannot read property 'Component' of undefined我必须相信这可能是问题所在。我看到在渲染/重新渲染之前查看执行 switch 语句检查 props 和 Component 的情况的开发工具doRender(),但它变得非常毛茸茸的匆忙通过。

我肯定想找到解决方案,因为它不仅仅影响我正在使用的技术。我还是个新手(还没有做过这方面的工作),幕后的 JS 比这位忍者训练中的黑带还要多。

0

一些观察结果:

  • 可以很好地配合next build && next start

  • TypeError: Cannot read property 'Component' of undefined 源于client/index.js这些行:

    const Component = evalScript(component).default // [1]
    //...
    let lastAppProps // [2]
    // ...
    async function doRender(/* ... */) {
    //...
    Component = Component || lastAppProps.Component // [3]
    // ....
    }

    在哪里component === window.__NEXT_DATA__.component

    加载页面时doRender()被多次调用。在第一个(和第二个?)执行中Component已声明为 a functionevaled script [1])。这时您可以观察显示的图片。现在,下一个时间doRender()被称为Componentis undefined,并且lastAppProps存在undefined( [2]) ——因此不具有属性Component( [3]) ——结果是TypeError

    为什么doRender()会被多次调用,Componentundefined还没弄清楚。

  • <img>服务器和客户端呈现的代码之间的不匹配是服务器呈现元素和客户端错误元素的结果next

☕️

9

@nikvm

感谢您对代码的深入解释。我一直被带回doRender();但很难理解其中的逻辑。我使用运行了测试存储库next build && next start,发现它在该用例中运行良好。我发现生产/lib/app.js标志绕过了错误消息的产生。

const ErrorDebug = process.env.NODE_ENV === 'production'
  ? null : require('./error-debug').default

我进入了client/index.js我的测试仓库,并开始console.logging看看我是否可以开始了解更多正在发生的事情。

var doRender = function () {
  var _ref4 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(_ref5) {
    var Component = _ref5.Component,
        props = _ref5.props,
        err = _ref5.err,
        emitter = _ref5.emitter;

    var _pathname, _query, appProps;
    console.log(Component); // See if the Component being passed is getting there.
    return _regenerator2.default.wrap(function _callee3$(_context3) {
      while (1) {
        console.log(_context3.prev); // just trying to understand all the different variables.
        console.log(_context3.next);
        switch (_context3.prev = _context3.next) {
          case 0:
            if (!(!props && Component && Component !== ErrorComponent && lastAppProps.Component === ErrorComponent)) {
              _context3.next = 5;
              break;
            }

            // fetch props if ErrorComponent was replaced with a page component by HMR
            _pathname = router.pathname, _query = router.query;
            _context3.next = 4;
            return (0, _utils.loadGetInitialProps)(Component, { err: err, pathname: _pathname, query: _query });

          case 4:
            props = _context3.sent;

          case 5:

            if (emitter) {
              console.log('before'); // does the code get here
              emitter.emit('before-reactdom-render', { Component: Component });
            }

            Component = Component || lastAppProps.Component;
            props = props || lastAppProps.props;

            appProps = { Component: Component, props: props, err: err, router: router, headManager: headManager };

            _reactDom2.default.render((0, _react.createElement)(_app2.default, appProps), container);

            if (emitter) {
              console.log('after'); // does the code get here
              emitter.emit('after-reactdom-render', { Component: Component });
            }

            lastAppProps = appProps;

          case 12:
          case 'end':
            return _context3.stop();
        }
      }
    }, _callee3, this);
  }));

所以我开始理解所引用的编号案例_context3,这就是我如何可以引用代码通过 switch 语句所采用的路径。我开始明白你所说的 Component 是什么意思undefined。下面是 Chrome 浏览器返回的屏幕截图console.logs

屏幕截图 2017-02-11 11 01 35 am

我要参加一个研讨会,但会在中部标准时间中午之后回来继续寻找脱节的地方。再次感谢您对代码的解释!

5

不会撒谎,我一直在浏览源代码,我感觉就像爱丽丝梦游仙境一样掉进了兔子洞。我能问一下,作为一名开发人员,您什么时候开始理解这里如此抽象的代码?我现在只是试图阅读代码,感觉很不够。

2

似乎是缓存问题:当我refresh在 Chrome 中单击时,我在一个非常简单的应用程序中遇到了同样的问题。当我进行硬刷新shift + refresh以绕过缓存时工作正常。

0

@rockchalkwushock @czzarr 参见#1208

9

@rockchalkwushock 希望获得一些有关您特别困惑的文件的反馈,以便我们可以改进相关领域/添加评论以提供指导。

我们确实计划很快在 Wiki 中编写一些“内部文档”。

1

@rauchg

我会在周一或周二晚上抽出一些时间,写下我感到困惑的要点。归根结底,这是一次深入研究源代码的新手。一开始有点震惊;它不一定与我在编码生涯的前 6 个月编写的代码相同。我将在此处引用有关此问题的要点,并标记您或 Next.js 开发团队的任何其他成员。

8

@timneutkens 我在使用 next 2.1.1 时仍然遇到这个问题。清除了我的 .next 目录,清除了浏览器缓存...仍然是一个问题

1

我也是。 ?

1

删除babel-plugin-add-module-export为我修复了它。不知道为什么或如何,但是......

1

很确定这与缓存有关。与你类似@erikras,我删除了yarn.lock和node_modules,yarn安装,提交新的yarn文件并推送(似乎在aws上清除了内容)并且应用程序可以工作

1

@erikras 谢谢。你救了我的命。我遇到了同样的问题。从 .babelrc 中删除后babel-plugin-module-resolver,问题消失了。不知道为什么,但它有效。

babel 插件看起来有些冲突。

1

从 .babelrc 中删除 babel-plugin-add-module-export 也为我解决了这个问题。但为什么?

1

我确实有下面的代码: import { React } from 'react'; 并且我收到了错误:“无法读取未定义的属性‘组件’”

我去掉了大括号,它工作得很好 import React from 'react'; 我得出了一个结论:我需要学习 ES6 :walking_man:

1

尝试这个:

import * as React from 'react';