我找不到使用 React 路由器 6 和 useContext 挂钩将数据传递给所有孩子的方法。当我用我的 Context.Provider 包装 <Routes></Routes>
并使用组件内的 Context.Consumer 调用它时,会出现错误:
错误:找不到名称“ShopContext”。
1.带有路由和Context.Provider的App.tsx
import React, { useState, createContext } from 'react';
import './App.scss';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from '../../pages/Home';
import SharedLayout from '../../layouts/SharedLayout';
import Artists from '../../pages/Artists';
import Contact from '../../pages/Contact';
import NotFound from '../../pages/NotFound';
import { Shop } from '../../interfaces/Shop';
import Data from '../../data.json';
function App() {
const [Infos] = useState<Shop>(Data)
const ShopContext = createContext({})
return (
<BrowserRouter>
<ShopContext.Provider value={Infos}>
<Routes>
<Route path='/' element={<SharedLayout />}>
<Route index element={<Home />} />
<Route path='artists' element={<Artists />}/>
<Route path='contact' element={<Contact />}/>
<Route path='*' element={<NotFound />} />
</Route>
</Routes>
</ShopContext.Provider>
</BrowserRouter>
)}
export default App;
和子组件:
import React, { useContext } from 'react';
function Artists(){
const shop = useContext(ShopContext)
return <>
Artists
</>
}
export default Artists;
我试过了:
包装包含 SharedLayout 的第一个路由 ==> 不起作用,路由必须是
的直接子级<Routes>
像这样将每个组件包装在每个 Route 中:
<BrowserRouter> <Routes> <Route path='/' element={ <ShopContext.Provider value={Infos}> <SharedLayout /> </ShopContext.Provider> }> <Route index element={ <ShopContext.Provider value={Infos}> <Home /> </ShopContext.Provider> } /> <Route path='artists' element={ <ShopContext.Provider value={Infos}> <Artists /> </ShopContext.Provider> }/> <Route path='contact' element={ <ShopContext.Provider value={Infos}> <Contact /> </ShopContext.Provider> }/> <Route path='*' element={<NotFound />} /> </Route> </Routes> </BrowserRouter>
)
回答1
问题
ShopContext
React 上下文应该在任何 React 组件之外声明。通过在 App
中声明它,每次 App
渲染时都会创建一个新的上下文。因为 ShopContext
是在 App
内声明的,所以它没有被定义为与路由组件中的 useContext
钩子一起使用,试图使用上下文 value。
解决方案
将 ShopContext
移动到它自己的文件中,以便可以创建和导出/导入以供使用。
例子:
ShopContext
import React, { useContext, useState, createContext } from 'react';
const ShopContext = createContext({});
const ShopProvider = ({ children }) => {
const [infos, setInfos] = useState<Shop>(Data);
... business logic to set/update infos state, etc ...
return (
<ShopContext.Provider value={infos}>
{children}
</ShopContext.Provider>
);
};
export useShopContext = () => useContext(ShopContext);
export default ShopProvider;
应用程序
import ShopProvider from '../path/to/ShopProvider';
function App() {
return (
<BrowserRouter>
<ShopProvider>
<Routes>
<Route path='/' element={<SharedLayout />}>
<Route index element={<Home />} />
<Route path='artists' element={<Artists />}/>
<Route path='contact' element={<Contact />}/>
<Route path='*' element={<NotFound />} />
</Route>
</Routes>
</ShopProvider>
</BrowserRouter>
);
}
艺术家
import { useShopContext } from '../path/to/ShopProvider';
function Artists(){
const shop = useShopContext();
return (
<>
Artists
</>
);
}