前言
我通过 vite
构建了一个 react
应用并使用 react.lazy
来懒加载组件,但是在使用过程中 一直提示 Fast refresh only works when a file only exports components. Move your component(s) to a separate file.eslint(react-refresh/only-export-components)
。这里简单的记录下问题的修复方式。
复现方式
先定义一组路由并导出
// src/router/index.jsx
import { lazy } from "react"
import { Navigate } from "react-router-dom"
const Home = lazy(() => import("../views/home"))
const routes = [
{ path: "/", element: <Navigate to="/home" /> },
{ path: "/home", element: <Home /> },
]
export default router
在 main.jsx
中使用简洁的 URL <BrowserRouter>
将当前位置存储在浏览器地址栏中,并使用浏览器内置的历史堆栈进行导航。
// src/main.jsx
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import { BrowserRouter } from "react-router-dom"
ReactDOM.createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
</BrowserRouter>
)
在 App.jsx
使用钩子函数 useRoutes
的返回一个有效的 React 元素来呈现路由树。
// src/App.jsx
import { useRoutes } from "react-router-dom"
import routes from './router/index'
function App() {
return (
<>
<div className="page">
{ useRoutes(routes) }
</div>
</>
)
}
export default App
但是在 router/index.jsx
中一直会提示如下错误:
解决措施
这里有两种解决方案:
-
为所有文件的此规则添加禁用注释。这实际上不会打破快速刷新。
-
导出呈现路由器提供程序的组件,而不是导出路由器。
在不修改原有配置的基础上我们推荐使用第二种方式进行修改,而且也是副作用最小的方式。
1、在 router\index.jsx
文件中使用 createBrowserRouter
这个 React Router Web 项目推荐使用的路由并使用 RouterProvider
导出路由。修改代码如下:
import { lazy } from "react"
import { Navigate, createBrowserRouter, RouterProvider } from "react-router-dom"
const Home = lazy(() => import("../views/home"))
const routes = [
{ path: "/", element: <Navigate to="/home" /> },
{ path: "/home", element: <Home /> },
]
const router = createBrowserRouter(routes)
const Routes = () => {
return <RouterProvider router={router} />
}
export default Routes
2、在 main.jsx
中直接渲染 App
组件即可
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
3、在 App.jsx
中直接使用 router\index.jsx
中导出的函数式组件,修改代码如下:
import Routes from "./router";
function App() {
return (
<>
<div className="page">
<Routes></Routes>
</div>
</>
)
}
export default App