【问题标题】:Jest & react-router-dom: React.createElement: type is invalid -- expected a string (for built-in components) ... but got: undefinedJest 和 react-router-dom: React.createElement: type is invalid - 期望一个字符串(用于内置组件)......但得到:未定义
【发布时间】:2020-04-23 05:13:28
【问题描述】:

我正在为具有来自react-router-domLink 的组件编写测试。

组件本身可以正常工作,不会出现任何错误或警告。

但是,当组件使用来自enzymeshallow 呈现时,它会在控制台中显示以下错误消息。

警告:React.createElement:类型无效 - 应为字符串(用于内置组件)或类/函数(用于复合组件)但得到:未定义。

您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。

据我研究,apparently 当您错误地导入 React 模块(或组件)时会发生此错误。

例如

import Link from 'react-router-dom'; // Wrong!
import { Link } from 'react-router-dom'; // Correct!

但是,就我而言,Link 已正确导入,但仍会显示上述警告消息。

这是组件的 sn-p。

import React from 'react';
import { Link, useHistory } from 'react-router-dom';
// other modules here

const ListItem = (props) => {
  const history = useHistory();
  const queryParameter = _.get(history, 'location.search', '');
  const pathName = `/blah/${props.id}${queryParameter}`;

  return (
    <li>
      <Link to={pathName}>
        <div>blah blah...</div>
      </Link>
    </li>
  );
};

(当我注释掉&lt;Link&gt;时,警告消息将从控制台消失。因此,使用useHistory()应该与警告无关)

jest.mock('react-router-dom', () => ({
  useHistory: jest.fn()
}));

describe('ListItem', () => {
  const baseProps = { /* initial props here*/ };

  it("renders the name", () => {
    const wrapper = shallow(<ListItem {...baseProps} />);
    // the line above shows the warning message in the console
  });
});

我完全不知道。 任何建议将不胜感激。

【问题讨论】:

  • 我遇到了同样的问题!你找到解决方案了吗?

标签: reactjs react-router jestjs enzyme react-router-dom


【解决方案1】:

听起来您没有导入正确的文件(如果您有一个 .(s)csstest.js 文件与组件同名并位于同一根目录中,则可能会导入错误的文件webpack 到测试文件中——因此,我建议指定组件名称和扩展名:index.jsListItem.js)。否则,您可能忘记导出 ListItem 组件。

工作示例(此示例使用mountRouter -- 单击Test 选项卡运行测试):


components/ListItem/index.js

import React from "react";
import get from "lodash/get";
import { Link, useHistory } from "react-router-dom";

function ListItem({ children, id, destination }) {
  const history = useHistory();
  const query = get(history, ["location", "search"]);

  return (
    <li style={{ margin: 0, padding: 0 }}>
      <Link to={`${destination}/${id}${query}`}>
        <div>{children}</div>
      </Link>
    </li>
  );
}

export default ListItem;

components/ListItem/__tests__/ListItem.test.js

import React from "react";
import { mount } from "enzyme";
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";
import ListItem from "../index.js";

const children = "Test";
const id = 1;
const destination = "/home";
const query = "?id=1";
const initialPath = `${destination}/${id}${query}`;

const history = createMemoryHistory({
  initialEntries: [initialPath]
});

const initProps = {
  children,
  id,
  destination
};

const wrapper = mount(
  <Router history={history}>
    <ListItem {...initProps} />
  </Router>
);

describe("ListItem", () => {
  afterAll(() => {
    wrapper.unmount();
  });

  it("renders the children", () => {
    expect(wrapper.find("div").text()).toEqual(children);
  });

  it("renders a Link that contains destination, params.id and query", () => {
    expect(wrapper.find("Link").props().to).toEqual(
      `${destination}/${id}${query}`
    );
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-13
    • 2017-06-03
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 2018-04-17
    相关资源
    最近更新 更多