You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带Props的React组件中使用react-router-dom Link报错求助

问题分析与修复方案

核心问题:测试时缺少Router上下文

Link组件依赖react-router提供的上下文(由BrowserRouter/HashRouter等容器组件创建)才能正常工作。你在测试中直接渲染Item组件,没有用BrowserRouter包裹,导致上下文为null,触发了Cannot destructure property 'basename'...的错误。

额外问题1:Item组件的Props解构错误

你的Item组件参数写成了({info},{addCart}),这是错误的——函数组件的props是单个对象,应该改成({info, addCart}),否则addCart会被解析为undefined,点击按钮时会触发调用错误。

额外问题2:测试用例的调用逻辑错误

第二个测试里,你渲染组件时传了addCart={addCartMock(details)},这会直接执行mock函数并传入参数,正确的做法是传递mock函数本身addCart={addCartMock},点击按钮后再验证调用情况。


修改后的代码

item.js

import { Link } from "react-router-dom";

// 修正props解构方式
const Item = ({ info, addCart }) => {
  return (
    <>
      <Link to="/"><button>X</button></Link>
      <img src={info.pic} alt={info.title} />
      <h1>{info.title}</h1>
      <p>{info.description}</p>
      <button onClick={() => addCart(info)}>Add</button>
    </>
  );
};

export default Item;

item.test.js

import React from 'react';
import { render, cleanup, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import Item from './item';
// 导入BrowserRouter用于提供上下文
import { BrowserRouter } from 'react-router-dom';

afterEach(cleanup);
const details = { pic: `a pic`, title: `a title`, description: `a description` };
const addCartMock = jest.fn();

// 封装带Router的渲染函数,避免重复代码
const renderWithRouter = (component) => {
  return render(<BrowserRouter>{component}</BrowserRouter>);
};

test(`Content renders`, () => {
  // 使用封装的renderWithRouter渲染组件
  renderWithRouter(<Item info={details} addCart={addCartMock} />);

  const image = screen.getByAltText(`${details.title}`);
  expect(image).toBeInTheDocument();
  expect(image).toHaveAttribute(`src`, `${details.pic}`);
  expect(screen.getByRole(`heading`, { name: details.title })).toBeInTheDocument();
  expect(screen.getByText(`${details.description}`)).toBeInTheDocument();
  expect(screen.getByRole(`button`, { name: `Add` })).toBeInTheDocument();
  expect(screen.getByRole(`button`, { name: `X` })).toBeInTheDocument();
});

test(`Add button click event`, () => {
  renderWithRouter(<Item info={details} addCart={addCartMock} />);

  userEvent.click(screen.getByRole(`button`, { name: `Add` }));
  expect(addCartMock).toHaveBeenCalledWith(details);
});

内容的提问来源于stack exchange,提问作者wavesinaroom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:55:24