React懒加载组件在动态路由上未被加载

7
我在动态路由中使用了React的lazy和suspense,但无法渲染懒加载组件。
我已经搜索了关于在路由上使用lazy的文章,但我没有看到任何人在动态(localhost:8080/dynamic/dynamic)路由上使用它。
在动态路由中加载组件对我有效,如果我使用静态路由,则懒加载也有效,但当我尝试将两者结合起来时,组件就无法加载。
以下是我的示例:
import Loader from './path/toFile';
import Home from './path/toFile';
const LazyLoadedComponent = lazy(() => import('./path/toFile'));

const App = () => {
 return(
  <Router>
     <Switch>

        // Home has multiple views controlled by buttons
        // A view contains selections with corresponding id
       <Route exact path="/:viewType?" component={Home} /> 

       // this component doesn't load when I select something which links me to this dynamic route.
       <Suspense fallback={Loader}>
         <Route path="/viewType/:selectionId" component={LazyLoadedComponent} />
       </Suspense>

     </Switch>
   </Router>
 )
}

我希望在进入该路由时只加载一次组件。 但结果是当我从选择中选择一个时,它只显示带有空白的 index.html。 我没有看到任何错误产生。

4个回答

8
我认为,在使用React的Suspense或lazy时没有问题,只是使用了Switch的方式不正确。
正如React路由文档所述:

<Switch>的所有子元素都应该是<Route><Redirect>元素。只有第一个与当前位置匹配的子元素将被渲染。

因此,Switch组件可能无法识别由Suspense组件包装的Route。
例如:
import Loader from './path/toFile';
import Home from './path/toFile';
const LazyLoadedComponent = lazy(() => import('./path/toFile'));

const App = () => {
 return(
   <Router>
     <Suspense fallback={Loader}>
       <Switch>
         <Route exact path="/:viewType?" component={Home} /> 
         <Route path="/viewType/:selectionId" component={LazyLoadedComponent} />
       </Switch>
     </Suspense>
   </Router>
 )
}

这里是一个在 CodeSandbox 上的示例:https://codesandbox.io/s/async-react-router-v4-w-suspense-8p1t6


更新你的答案中的 blockquote。你漏掉了一些标签。 - ravibagul91
谢谢你的建议,这实际上是我代码的当前结构,但在之后会产生一个错误404,它无法加载chunk(0.js),因为它被调用在错误的位置(localhost:8080/viewType/0.js),应该是(localhost:8080/0.js)或者也许我需要配置我的webpack将chunk文件生成到自定义位置。我正在尝试寻找解决方案,我知道我的文件确实存在,因为我可以使用后面的链接访问_0.js_。如果你有什么解决办法,我将非常感激。再次感谢。 - jhimanjhi

2
我已经找到了解决方案...或者在我的情况下是这样的。
我在webpack.config.js中添加了bundle的publicPath。
我在webpack配置文档中找到了相关信息。
output: {
        publicPath: '/',
      },

问题在于上次我只是刷新了页面,知道有热模块安装,但它没有更新我的配置。

所以在重新启动服务器后,我看到了这行:

webpack输出从(我声明的publicPath)提供

虽然我在这个问题上花费了比应该更多的时间,但现在它可以工作了,感谢所有评论。

最初的回答:


这个对我也起作用了,非常有趣。我会进一步调查,确保它没有任何不利影响,但似乎比其他选择要简单得多。 - kroe

1
尝试this
 <Suspense fallback={Loader}>
   <Switch>
     <Route path="/viewType/:selectionId" />
         <LazyLoadedComponent />
     </Route>
   </Switch>
 </Suspense>

嗨,感谢您的建议。我已经尝试过这个方法,但结果仍然相同。我认为问题出在块文件上,因为它被加载到了错误的位置。您提供的文章也很有帮助,特别是动态导入部分,但是它们都和我的之前的代码产生了相同的结果。 - jhimanjhi

0

我通过在webpack.config中进行一些额外的更改来解决了这个问题。 首先使用

npm run eject来弹出配置。

webpack.config.js

path: isEnvProduction
            ? path.resolve(__dirname, "..", "build")
            : undefined,
    
filename: isEnvProduction
            ? "[name].js"
            : isEnvDevelopment && "static/js/bundle.js",
    
chunkFilename: isEnvProduction
            ? "[name].chunk.js"
    
publicPath: "/",

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接