当组件已经在里面时,如何" useHref() may be used only in the context of a <Router> component"解析器<Router&



我目前正在为我的react应用程序编写Jest测试。

当我为<Container />运行测试时,错误消息显示:

"useHref((只能在组件的上下文中使用">

但是,<Container />已经在<Router/>内部。

我在这里读过其他类似的问题,答案都说把组件放在<Router/>中,这就是我所做的。

Container.test.js

import { render, unmountComponentAtNode } from 'react-dom';
import Container from '../components/Container.tsx';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { configure, shallow, mount } from 'enzyme';
import { Provider, useDispatch } from 'react-redux';
import { act } from "react-dom/test-utils";
import configureStore from 'redux-mock-store';
configure({adapter: new Adapter()});
const initState = { allCard: [], expansions: [] };
const mockStore = configureStore();
const wrapper = mount(<Provider store={mockStore(initState)}><Container/></Provider>);
describe('Container', () => {
let container = null;
beforeEach(() => {
// setup a DOM element as a render target
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// cleanup on exiting
unmountComponentAtNode(container);
container.remove();
container = null;
});
it('renders itself and its children without crashing', () => {
render(<Provider store={mockStore(initState)}><Container /></Provider>, container);
});
it('renders itself without crashing', () => {
const tree = wrapper.render();
expect(tree.toJSON).toMatchSnapshot();
});
});

App.js

import './App.css';
import Container from './components/Container';
import About from './components/RouteComponents/About';
import NavBar from './components/NavBar';
import Tutorials from './components/RouteComponents/Tutorials';
import Suggest from './components/RouteComponents/Suggest';
import Report from './components/RouteComponents/Report';
import { Route, Routes, BrowserRouter as Router } from 'react-router-dom';
import GlobalStyles from './components/styled/Globals.styled';
import { useState, createContext } from 'react';
function App() {
const [ darkMode, setDarkMode ] = useState(false);
return (
<Router> 
{darkMode? <GlobalStyles/> : null}
<div className="App">
<NavBar darkMode={darkMode} setDarkMode={setDarkMode}/>
<Routes>
<Route path='/' element= {<UserContext.Provider value={darkMode}>
<Container />
</UserContext.Provider>} />
<Route path='/about' element={<About />} />
<Route path='/tutorial' element= {<Tutorials />} />
<Route path='/suggest' element={<Suggest />} />
<Route path='/report' element= {<Report />} />
</Routes>
</div>
</Router>
);
}
export const UserContext = createContext(null);
export default App;

集装箱.tsx

import { useEffect, ReactElement } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';
import { useDispatch } from 'react-redux'
import ErrorBoundary from './ErrorBoundary';
import ExpansionView from './ExpansionView';
import DisplayView from './DisplayView';
import SearchCard from './SearchCard';
import MurlocTidehunter from '../image/murlocTidehunter.png';
import SelectExpanionsMurloc from '../image/selectExpansions.png';
import { StyledContainer } from './styled/Container.styled';
import { eliminateMurloc } from '../utils/eliminateMurloc';
// Component - parent component that fetches allCard once when app launches
const Container = (): ReactElement => {
const dispatch = useDispatch();

useEffect(() => {
const options: object = {
method: 'GET',
url: 'https://omgvamp-hearthstone-v1.p.rapidapi.com/cards',
params: {collectible: '1'},
headers: {
'x-rapidapi-host': 'omgvamp-hearthstone-v1.p.rapidapi.com',
'x-rapidapi-key': 'xxxxxxxxxx'
}
};

// function to fetch all collectible cards from hearthstone api
const fetchAllCards = async (): Promise<any> => {
try {
const response = await axios.request(options); 
dispatch({type: 'SET_ALL_CARD', payload: response.data})
} catch(e) {
console.log(e)
}
}
fetchAllCards();
}, []);
return (
<StyledContainer>
<h1 id='hearthfin'>Hearthfin</h1>
<img id='tideHunter' className='deletableMurloc' src={MurlocTidehunter} alt="Hearthstone Murloc Analisis Videojuegos Zehngames - Murloc@seekpng.com" />
<img id='selectExpMurloc' className='deletableMurloc' onClick={() => eliminateMurloc('selectExpMurloc')} src={SelectExpanionsMurloc} alt="Murloc that say select expansions first!" />
<ErrorBoundary>
<ExpansionView /> 
</ErrorBoundary>
<ErrorBoundary>
<DisplayView />
</ErrorBoundary>
<p id='missingCard'>See a missing AOE card? Make a suggestion <Link to='suggest'>here!</Link></p>
<ErrorBoundary>
<SearchCard />
</ErrorBoundary>
<br/>

</StyledContainer>
);
}
export default Container;

您正在路由上下文之外呈现导航栏。路由器不知道链接试图链接的路由是它正在管理的。路由在直接导航到"/"是因为路由器在应用程序安装时知道URL

您需要模拟Link组件。在任何测试之前添加此项:

jest.mock('react-router-dom', () => ({
Link: (props) => {
return <a {...props} href={props.to} />;
},
}));

在您的"Container.tsx";文件,像这样包装组件:

import { BrowserRouter as Router } from 'react-router-dom';
<Router> 
<StyledContainer>
//jsx elements
</StyledContainer>
<Router> 

现在"链接";Container组件的不会混淆,因为Link会发现Router是其组件的包装器。

不要忘记从";js";文件剩下的和以前一样。

相关内容

最新更新